~aleteoryx/muditaos

9ff089462e3817417adb6931bc8dd80da695c4fc — KacperLewandowski 5 years ago d787563
[EGD-5073] Add UI modifications in Calendar after review

Changes mainly concern margins, positions, sizes etc of items in:
- Custom repeat window,
- New/Edit event window,
- No events window.
M module-apps/application-calendar/data/CalendarData.hpp => module-apps/application-calendar/data/CalendarData.hpp +6 -0
@@ 6,6 6,12 @@
#include <module-gui/gui/SwitchData.hpp>
#include "application-calendar/widgets/CalendarStyle.hpp"

enum class EventAction
{
    Add,
    Edit
};

class EventRecordData : public gui::SwitchData
{
  protected:

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

#include "NewEditEventModel.hpp"
#include "AppWindow.hpp"
#include "application-calendar/widgets/NewEventCheckBoxWithLabel.hpp"
#include "module-apps/application-calendar/data/CalendarData.hpp"
#include "application-calendar/data/CalendarData.hpp"
#include "application-calendar/ApplicationCalendar.hpp"
#include "AppWindow.hpp"
#include <BottomBar.hpp>
#include <ListView.hpp>
#include <module-db/queries/calendar/QueryEventsAdd.hpp>
#include <module-db/queries/calendar/QueryEventsEdit.hpp>
#include <service-db/DBServiceAPI.hpp>
#include <time/time_conversion.hpp>
#include <module-apps/application-calendar/ApplicationCalendar.hpp>

NewEditEventModel::NewEditEventModel(app::Application *app, bool mode24H) : application(app), mode24H(mode24H)
{}


@@ 70,7 70,7 @@ void NewEditEventModel::createData(bool allDayEvent)
        [app]() { app->getCurrentWindow()->selectSpecialCharacter(); });

    allDayEventCheckBox = new gui::NewEventCheckBoxWithLabel(
        application, utils::localize.get("app_calendar_new_edit_event_allday"), true, this);
        application, utils::localize.get("app_calendar_new_edit_event_allday"), this);

    dateItem = new gui::EventDateItem();



@@ 104,10 104,12 @@ void NewEditEventModel::createData(bool allDayEvent)
    startTime->setConnectionToDateItem(dateItem);
    endTime->setConnectionToDateItem(dateItem);

    allDayEventCheckBox->setConnectionToDateItem(dateItem);

    internalData.push_back(eventNameInput);
    internalData.push_back(allDayEventCheckBox);
    internalData.push_back(dateItem);
    if (!allDayEvent) {
        internalData.push_back(dateItem);
        internalData.push_back(startTime);
        internalData.push_back(endTime);
    }


@@ 145,9 147,6 @@ void NewEditEventModel::loadData(std::shared_ptr<EventsRecord> record)
                            TimePointToHourMinSec(TimePointNow()).hours() +
                            TimePointToHourMinSec(TimePointNow()).minutes();
        record->date_till = record->date_from + std::chrono::hours(1);
        if (dateItem->onLoadCallback) {
            dateItem->onLoadCallback(record);
        }
        if (startTime->onLoadCallback) {
            startTime->onLoadCallback(record);
        }


@@ 168,7 167,6 @@ void NewEditEventModel::loadRepeat(const std::shared_ptr<EventsRecord> &record)

void NewEditEventModel::loadDataWithoutTimeItem()
{
    internalData.erase(std::find(internalData.begin(), internalData.end(), dateItem));
    internalData.erase(std::find(internalData.begin(), internalData.end(), startTime));
    internalData.erase(std::find(internalData.begin(), internalData.end(), endTime));
    list->rebuildList();


@@ 193,7 191,7 @@ void NewEditEventModel::reloadDataWithTimeItem()
    list->rebuildList();
}

void NewEditEventModel::saveData(std::shared_ptr<EventsRecord> event, bool edit)
void NewEditEventModel::saveData(std::shared_ptr<EventsRecord> event, EventAction action)
{
    for (auto &item : internalData) {
        if (item->onSaveCallback) {


@@ 201,19 199,20 @@ void NewEditEventModel::saveData(std::shared_ptr<EventsRecord> event, bool edit)
        }
    }

    if (edit) {
    if (action == EventAction::Edit) {
        auto record = event.get();
        record->reminder_fired = TIME_POINT_INVALID;
        if (record->title != "") {
        if (!record->title.empty()) {
            DBServiceAPI::GetQuery(
                application, db::Interface::Name::Events, std::make_unique<db::query::events::Edit>(*record));
        }
        const uint32_t numberOfIgnoredWindows = 3;
        application->returnToPreviousWindow(numberOfIgnoredWindows);
        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));
    }
    else {
        auto record = event.get();
        if (record->title != "") {
        if (!record->title.empty()) {
            DBServiceAPI::GetQuery(
                application, db::Interface::Name::Events, std::make_unique<db::query::events::Add>(*record));


M module-apps/application-calendar/models/NewEditEventModel.hpp => module-apps/application-calendar/models/NewEditEventModel.hpp +7 -3
@@ 8,18 8,22 @@
#include "application-calendar/widgets/TextWithLabelItem.hpp"
#include "application-calendar/widgets/EventTimeItem.hpp"
#include "application-calendar/widgets/SeveralOptionsItem.hpp"
#include "application-calendar/widgets/CheckBoxWithLabelItem.hpp"
#include "application-calendar/widgets/EventDateItem.hpp"
#include "InternalModel.hpp"
#include <ListItemProvider.hpp>

namespace gui
{
    class NewEventCheckBoxWithLabel; // fw declaration
}

class NewEditEventModel : public app::InternalModel<gui::CalendarListItem *>, public gui::ListItemProvider
{
    app::Application *application = nullptr;
    bool mode24H                  = false;

    gui::TextWithLabelItem *eventNameInput          = nullptr;
    gui::CheckBoxWithLabelItem *allDayEventCheckBox = nullptr;
    gui::NewEventCheckBoxWithLabel *allDayEventCheckBox = nullptr;
    gui::EventDateItem *dateItem                    = nullptr;
    gui::EventTimeItem *startTime                   = nullptr;
    gui::EventTimeItem *endTime                     = nullptr;


@@ 33,7 37,7 @@ class NewEditEventModel : public app::InternalModel<gui::CalendarListItem *>, pu
    void loadRepeat(const std::shared_ptr<EventsRecord> &record);
    void loadDataWithoutTimeItem();
    void reloadDataWithTimeItem();
    void saveData(std::shared_ptr<EventsRecord> event, bool edit);
    void saveData(std::shared_ptr<EventsRecord> event, EventAction action);
    void addReapetedRecords(std::shared_ptr<EventsRecord> event);

    [[nodiscard]] unsigned int getMinimalItemHeight() const override;

M module-apps/application-calendar/widgets/CalendarStyle.hpp => module-apps/application-calendar/widgets/CalendarStyle.hpp +14 -7
@@ 44,6 44,7 @@ namespace style
            inline constexpr auto month_year_height = 60;
            inline constexpr auto week_days_number  = 7;
            inline constexpr auto max_weeks_number  = 6;
            inline constexpr auto leftMargin        = 10;

            inline constexpr auto cross_x    = 48;
            inline constexpr auto cross_y    = 55;


@@ 110,11 111,12 @@ namespace style

                namespace eventTime
                {
                    inline constexpr auto height           = 106;
                    inline constexpr auto margin           = 21;
                    inline constexpr auto height           = 107;
                    inline constexpr auto margin           = 20;
                    inline constexpr auto separator        = 30;
                    inline constexpr auto time_input_12h_w = 120;
                    inline constexpr auto time_input_24h_w = 195;
                    inline constexpr auto hBox_h           = height - 1.25 * margin;
                } // namespace eventTime

                namespace checkBox


@@ 128,15 130,20 @@ namespace style
                namespace severalOptions
                {
                    inline constexpr auto height    = 63;
                    inline constexpr auto label_h   = 30;
                    inline constexpr auto arrow_w_h = 20;
                    inline constexpr auto label_h   = 20;
                    inline constexpr auto arrow_w_h = 12;
                    inline constexpr auto margin    = 5;
                    inline constexpr auto hBox_h    = height - label_h - margin;
                    inline constexpr auto option_w =
                        style::window::default_body_width - 2 * arrow_w_h - 2 * style::window::calendar::leftMargin;
                } // namespace severalOptions

                namespace textWithLabel
                {
                    inline constexpr auto height        = 80;
                    inline constexpr auto description_h = 30;
                    inline constexpr auto text_input_h  = 40;
                    inline constexpr auto height        = 63;
                    inline constexpr auto description_h = 20;
                    inline constexpr auto text_input_h  = 37;
                    inline constexpr auto margin        = 6;
                } // namespace textWithLabel
            }     // namespace item
        };        // namespace calendar

M module-apps/application-calendar/widgets/CheckBoxWithLabelItem.cpp => module-apps/application-calendar/widgets/CheckBoxWithLabelItem.cpp +17 -32
@@ 7,52 7,38 @@
#include <ListView.hpp>
#include <Style.hpp>
#include <Utils.hpp>
#include <InputEvent.hpp>

namespace gui
{

    CheckBoxWithLabelItem::CheckBoxWithLabelItem(app::Application *application,
                                                 const std::string &description,
                                                 std::shared_ptr<WeekDaysRepeatData> data,
                                                 bool checkIsOnLeftBarSide)
        : app(application), checkBoxData(std::move(data)), checkIsOnLeftBarSide(checkIsOnLeftBarSide)
                                                 std::shared_ptr<WeekDaysRepeatData> data)
        : app(application), checkBoxData(std::move(data))
    {
        app = application;
        assert(app != nullptr);

        setMinimumSize(style::window::default_body_width, style::window::calendar::item::checkBox::height);
        setMargins(gui::Margins(style::margins::small, style::window::calendar::item::checkBox::margin_top, 0, 0));
        setMargins(gui::Margins(
            style::window::calendar::leftMargin, style::window::calendar::item::checkBox::margin_top, 0, 0));
        setEdges(RectangleEdge::None);

        hBox = new gui::HBox(this, 0, 0, 0, 0);
        hBox->setEdges(gui::RectangleEdge::None);

        if (checkIsOnLeftBarSide) {
            checkBox = new gui::CheckBox(
                hBox,
                0,
                0,
                0,
                0,
                [=](const UTF8 &text) {
                    app->getCurrentWindow()->bottomBarTemporaryMode(text, BottomBar::Side::LEFT, false);
                },
                [=]() { app->getCurrentWindow()->bottomBarRestoreFromTemporaryMode(); },
                checkIsOnLeftBarSide);
        }
        else {
            checkBox = new gui::CheckBox(
                hBox,
                0,
                0,
                0,
                0,
                [=](const UTF8 &text) {
                    app->getCurrentWindow()->bottomBarTemporaryMode(text, BottomBar::Side::CENTER, false);
                },
                [=]() { app->getCurrentWindow()->bottomBarRestoreFromTemporaryMode(); },
                checkIsOnLeftBarSide);
        }
        checkBox = new gui::CheckBox(
            hBox,
            0,
            0,
            0,
            0,
            [=](const UTF8 &text) {
                app->getCurrentWindow()->bottomBarTemporaryMode(text, BottomBar::Side::LEFT, false);
            },
            [=]() { app->getCurrentWindow()->bottomBarRestoreFromTemporaryMode(); });

        checkBox->setMinimumSize(style::window::calendar::item::checkBox::input_box_label_w,
                                 style::window::calendar::item::checkBox::height);
        checkBox->activeItem = false;


@@ 62,7 48,7 @@ namespace gui
                                         style::window::calendar::item::checkBox::height);
        descriptionLabel->setMargins(gui::Margins(style::margins::very_big, 0, 0, 0));
        descriptionLabel->setEdges(gui::RectangleEdge::None);
        descriptionLabel->setAlignment(Alignment(gui::Alignment::Horizontal::Left, gui::Alignment::Vertical::Center));
        descriptionLabel->setAlignment(Alignment(gui::Alignment::Horizontal::Left, gui::Alignment::Vertical::Top));
        descriptionLabel->setFont(style::window::font::medium);
        descriptionLabel->activeItem = false;
        descriptionLabel->setText(description);


@@ 83,7 69,6 @@ namespace gui
            }
            else {
                descriptionLabel->setFont(style::window::font::medium);
                setFocusItem(nullptr);
            }
            return true;
        };

M module-apps/application-calendar/widgets/CheckBoxWithLabelItem.hpp => module-apps/application-calendar/widgets/CheckBoxWithLabelItem.hpp +1 -3
@@ 18,7 18,6 @@ namespace gui
        gui::HBox *hBox           = nullptr;
        app::Application *app     = nullptr;
        std::shared_ptr<WeekDaysRepeatData> checkBoxData = nullptr;
        bool checkIsOnLeftBarSide = false;

        virtual void applyCallbacks();
        void setCheckBoxes();


@@ 26,8 25,7 @@ namespace gui
      public:
        CheckBoxWithLabelItem(app::Application *application,
                              const std::string &description,
                              std::shared_ptr<WeekDaysRepeatData> data = nullptr,
                              bool checkIsOnLeftBarSide                = false);
                              std::shared_ptr<WeekDaysRepeatData> data = nullptr);
        virtual ~CheckBoxWithLabelItem() override = default;

        gui::Label *descriptionLabel = nullptr;

M module-apps/application-calendar/widgets/EventDateItem.cpp => module-apps/application-calendar/widgets/EventDateItem.cpp +76 -40
@@ 6,16 6,16 @@
#include <ListView.hpp>
#include <Style.hpp>
#include <time/time_conversion.hpp>
#include <module-utils/date/include/date/date.h>
#include <time/time_date_validation.hpp>

namespace gui
{

    namespace dateItem = style::window::calendar::item::eventTime;
    EventDateItem::EventDateItem()
    {
        setMinimumSize(style::window::default_body_width, style::window::calendar::item::eventTime::height);
        setMinimumSize(style::window::default_body_width, dateItem::height);
        setEdges(RectangleEdge::None);
        setMargins(gui::Margins(style::margins::small, style::window::calendar::item::eventTime::margin, 0, 0));
        setMargins(gui::Margins(style::window::calendar::leftMargin, dateItem::margin, 0, 0));

        buildInterface();
        applyCallbacks();


@@ 28,72 28,60 @@ namespace gui
        vBox->activeItem = false;

        labelsHBox = new gui::HBox(vBox, 0, 0, 0, 0);
        labelsHBox->setMinimumSize(style::window::default_body_width,
                                   style::window::calendar::item::eventTime::separator);
        labelsHBox->setMinimumSize(style::window::default_body_width, dateItem::margin);
        labelsHBox->setMargins(gui::Margins(0, 0, 0, dateItem::margin / 4));
        labelsHBox->setEdges(RectangleEdge::None);
        labelsHBox->activeItem = false;

        dayLabel = new gui::Label(labelsHBox, 0, 0, 0, 0);
        dayLabel->setMinimumSize(style::window::calendar::item::eventTime::time_input_12h_w,
                                 style::window::calendar::item::eventTime::separator);
        dayLabel->setEdges(RectangleEdge::None);
        dayLabel->setAlignment(Alignment(gui::Alignment::Horizontal::Left, gui::Alignment::Vertical::Center));
        dayLabel->setFont(style::window::font::small);
        dayLabel->activeItem = false;
        applyLabelSpecificProperties(dayLabel);
        dayLabel->setText(utils::localize.get("app_settings_title_day"));

        monthLabel = new gui::Label(labelsHBox, 0, 0, 0, 0);
        monthLabel->setMinimumSize(style::window::calendar::item::eventTime::time_input_12h_w,
                                   style::window::calendar::item::eventTime::separator);
        monthLabel->setMargins(gui::Margins(style::window::calendar::item::eventTime::separator, 0, 0, 0));
        monthLabel->setEdges(RectangleEdge::None);
        monthLabel->setAlignment(Alignment(gui::Alignment::Horizontal::Left, gui::Alignment::Vertical::Center));
        monthLabel->setFont(style::window::font::small);
        monthLabel->activeItem = false;
        applyLabelSpecificProperties(monthLabel);
        monthLabel->setMargins(gui::Margins(dateItem::separator, 0, 0, 0));
        monthLabel->setText(utils::localize.get("app_settings_title_month"));

        yearLabel = new gui::Label(labelsHBox, 0, 0, 0, 0);
        yearLabel->setMinimumSize(style::window::calendar::item::eventTime::time_input_12h_w,
                                  style::window::calendar::item::eventTime::separator);
        yearLabel->setMargins(gui::Margins(style::window::calendar::item::eventTime::separator, 0, 0, 0));
        yearLabel->setEdges(RectangleEdge::None);
        yearLabel->setAlignment(Alignment(gui::Alignment::Horizontal::Left, gui::Alignment::Vertical::Center));
        yearLabel->setFont(style::window::font::small);
        yearLabel->activeItem = false;
        applyLabelSpecificProperties(yearLabel);
        yearLabel->setMargins(gui::Margins(dateItem::separator, 0, 0, 0));
        yearLabel->setText(utils::localize.get("app_settings_title_year"));

        dateHBox = new gui::HBox(vBox, 0, 0, 0, 0);
        dateHBox->setMinimumSize(style::window::default_body_width,
                                 style::window::calendar::item::eventTime::height -
                                     style::window::calendar::item::eventTime::separator);
        dateHBox->setMinimumSize(style::window::default_body_width, dateItem::hBox_h);
        dateHBox->setEdges(RectangleEdge::None);
        dateHBox->activeItem = false;

        dayInput = new gui::Text(dateHBox, 0, 0, 0, 0);
        dayInput = new gui::Label(dateHBox, 0, 0, 0, 0);

        monthInput = new gui::Text(dateHBox, 0, 0, 0, 0);
        monthInput->setMargins(gui::Margins(style::window::calendar::item::eventTime::separator, 0, 0, 0));
        monthInput = new gui::Label(dateHBox, 0, 0, 0, 0);
        monthInput->setMargins(gui::Margins(dateItem::separator, 0, 0, 0));

        yearInput = new gui::Text(dateHBox, 0, 0, 0, 0);
        yearInput->setMargins(gui::Margins(style::window::calendar::item::eventTime::separator, 0, 0, 0));
        yearInput = new gui::Label(dateHBox, 0, 0, 0, 0);
        yearInput->setMargins(gui::Margins(dateItem::separator, 0, 0, 0));

        applyItemSpecificProperties(dayInput);
        applyItemSpecificProperties(monthInput);
        applyItemSpecificProperties(yearInput);
    }

    void EventDateItem::applyItemSpecificProperties(gui::Text *item)
    void EventDateItem::applyItemSpecificProperties(gui::Label *item)
    {
        item->setMinimumSize(style::window::calendar::item::eventTime::time_input_12h_w,
                             style::window::calendar::item::eventTime::height -
                                 style::window::calendar::item::eventTime::separator);
        item->setMinimumSize(dateItem::time_input_12h_w, dateItem::hBox_h);
        item->setEdges(RectangleEdge::Bottom);
        item->setAlignment(gui::Alignment(gui::Alignment::Horizontal::Center, gui::Alignment::Vertical::Center));
        item->setFont(style::window::font::largelight);
        item->setInputMode(new InputMode({InputMode::digit}));
        item->setPenFocusWidth(style::window::default_border_focus_w);
        item->setPenWidth(style::window::default_border_rect_no_focus);
        item->setEditMode(gui::EditMode::Edit);
    }

    void EventDateItem::applyLabelSpecificProperties(gui::Label *label)
    {
        label->setMinimumSize(dateItem::time_input_12h_w, dateItem::margin);
        label->setEdges(RectangleEdge::None);
        label->setAlignment(Alignment(gui::Alignment::Horizontal::Left, gui::Alignment::Vertical::Center));
        label->setFont(style::window::font::small);
        label->activeItem = false;
    }

    void EventDateItem::applyCallbacks()


@@ 140,6 128,10 @@ namespace gui
            monthInput->setText(std::to_string(static_cast<unsigned>(date.month())));
            yearInput->setText(std::to_string(static_cast<int>(date.year())));
        };

        setOnInputCallback(*dayInput);
        setOnInputCallback(*monthInput);
        setOnInputCallback(*yearInput);
    }

    bool EventDateItem::onDimensionChanged(const BoundingBox &oldDim, const BoundingBox &newDim)


@@ 199,4 191,48 @@ namespace gui
        return validateDate();
    }

    void EventDateItem::setDate(int keyValue, gui::Label &item)
    {
        auto itemValue = item.getText();
        auto key       = std::to_string(keyValue);
        if (itemValue == "0") {
            itemValue = key;
        }
        else {
            itemValue += key;
        }
        item.setText(itemValue);

        if (!utils::time::validateDate(dayInput->getText(), monthInput->getText(), yearInput->getText())) {
            item.setText(key);
        }
    }

    void EventDateItem::setOnInputCallback(gui::Label &dateInput)
    {
        dateInput.inputCallback = [&](Item &item, const InputEvent &event) {
            if (event.state != gui::InputEvent::State::keyReleasedShort) {
                return false;
            }
            if (auto value = gui::toNumeric(event.keyCode); value >= 0) {
                setDate(value, dateInput);
                return true;
            }
            else if (event.is(gui::KeyCode::KEY_PND)) {
                clearInput(dateInput);
                return true;
            }
            return false;
        };
    }

    void EventDateItem::clearInput(gui::Label &dateInput)
    {
        auto value = dateInput.getText();
        if (auto length = value.length(); length > 0) {
            value.removeChar(length - 1);
            dateInput.setText(value);
        }
    }

} /* namespace gui */

M module-apps/application-calendar/widgets/EventDateItem.hpp => module-apps/application-calendar/widgets/EventDateItem.hpp +8 -4
@@ 17,14 17,18 @@ namespace gui
        gui::Label *dayLabel   = nullptr;
        gui::Label *monthLabel = nullptr;
        gui::Label *yearLabel  = nullptr;
        gui::Text *dayInput    = nullptr;
        gui::Text *monthInput  = nullptr;
        gui::Text *yearInput   = nullptr;
        gui::Label *dayInput   = nullptr;
        gui::Label *monthInput = nullptr;
        gui::Label *yearInput  = nullptr;

        void buildInterface();
        void applyItemSpecificProperties(gui::Text *item);
        void applyItemSpecificProperties(gui::Label *item);
        void applyLabelSpecificProperties(gui::Label *label);
        void applyCallbacks();
        calendar::YearMonthDay validateDate();
        void setDate(int keyValue, gui::Label &item);
        void setOnInputCallback(gui::Label &dateInput);
        void clearInput(gui::Label &dateInput);

      public:
        EventDateItem();

M module-apps/application-calendar/widgets/EventTimeItem.cpp => module-apps/application-calendar/widgets/EventTimeItem.cpp +69 -80
@@ 6,10 6,11 @@
#include <ListView.hpp>
#include <Style.hpp>
#include <time/time_conversion.hpp>
#include <module-utils/date/include/date/date.h>
#include <time/time_date_validation.hpp>

namespace gui
{
    namespace timeItem = style::window::calendar::item::eventTime;

    EventTimeItem::EventTimeItem(const std::string &description,
                                 bool mode24H,


@@ 18,57 19,49 @@ namespace gui
        : mode24H{mode24H}, bottomBarTemporaryMode(std::move(bottomBarTemporaryMode)),
          bottomBarRestoreFromTemporaryMode(std::move(bottomBarRestoreFromTemporaryMode))
    {
        setMinimumSize(style::window::default_body_width, style::window::calendar::item::eventTime::height);
        setMinimumSize(style::window::default_body_width, timeItem::height);

        setEdges(RectangleEdge::None);
        setMargins(gui::Margins(style::margins::small, style::window::calendar::item::eventTime::margin, 0, 0));
        setMargins(gui::Margins(style::window::calendar::leftMargin, timeItem::margin, 0, 0));

        vBox = new gui::VBox(this, 0, 0, 0, 0);
        vBox->setEdges(gui::RectangleEdge::None);
        vBox->activeItem = false;

        descriptionLabel = new gui::Label(vBox, 0, 0, 0, 0);
        descriptionLabel->setMinimumSize(style::window::default_body_width,
                                         style::window::calendar::item::eventTime::separator);
        descriptionLabel->setMinimumSize(style::window::default_body_width, timeItem::margin);
        descriptionLabel->setMargins(gui::Margins(0, 0, 0, timeItem::margin / 4));
        descriptionLabel->setEdges(gui::RectangleEdge::None);
        descriptionLabel->setAlignment(Alignment(gui::Alignment::Horizontal::Left, gui::Alignment::Vertical::Center));
        descriptionLabel->setFont(style::window::font::small);
        descriptionLabel->activeItem = false;

        hBox = new gui::HBox(vBox, 0, 0, 0, 0);
        hBox->setMinimumSize(style::window::default_body_width,
                             style::window::calendar::item::eventTime::height -
                                 style::window::calendar::item::eventTime::separator);
        hBox->setMinimumSize(style::window::default_body_width, timeItem::hBox_h);
        hBox->setEdges(gui::RectangleEdge::None);
        hBox->activeItem = false;

        hourInput = new gui::Text(hBox, 0, 0, 0, 0);
        hourInput = new gui::Label(hBox, 0, 0, 0, 0);
        hourInput->setEdges(gui::RectangleEdge::Bottom);
        hourInput->setAlignment(gui::Alignment(gui::Alignment::Horizontal::Center, gui::Alignment::Vertical::Center));
        hourInput->setFont(style::window::font::largelight);
        hourInput->setInputMode(new InputMode({InputMode::digit}));
        hourInput->setPenFocusWidth(style::window::default_border_focus_w);
        hourInput->setPenWidth(style::window::default_border_rect_no_focus);
        hourInput->setEditMode(gui::EditMode::Edit);

        colonLabel = new gui::Label(hBox, 0, 0, 0, 0);
        colonLabel->setMinimumSize(style::window::calendar::item::eventTime::separator,
                                   style::window::calendar::item::eventTime::height -
                                       style::window::calendar::item::eventTime::separator);
        colonLabel->setMinimumSize(timeItem::separator, timeItem::hBox_h);
        colonLabel->setEdges(gui::RectangleEdge::None);
        colonLabel->setAlignment(Alignment(gui::Alignment::Horizontal::Center, gui::Alignment::Vertical::Center));
        colonLabel->setFont(style::window::font::medium);
        colonLabel->setText(":");
        colonLabel->activeItem = false;

        minuteInput = new gui::Text(hBox, 0, 0, 0, 0);
        minuteInput = new gui::Label(hBox, 0, 0, 0, 0);
        minuteInput->setEdges(gui::RectangleEdge::Bottom);
        minuteInput->setAlignment(gui::Alignment(gui::Alignment::Horizontal::Center, gui::Alignment::Vertical::Center));
        minuteInput->setFont(style::window::font::largelight);
        minuteInput->setInputMode(new InputMode({InputMode::digit}));
        minuteInput->setPenFocusWidth(style::window::default_border_focus_w);
        minuteInput->setPenWidth(style::window::default_border_rect_no_focus);
        minuteInput->setEditMode(gui::EditMode::Edit);

        descriptionLabel->setText(description);



@@ 97,8 90,6 @@ namespace gui

            if (focusedItem->onInput(event)) {
                uint32_t hours;
                uint32_t minutes;
                uint32_t autofill_hour;

                try {
                    hours = std::stoi(hourInput->getText().c_str());


@@ 108,25 99,7 @@ namespace gui
                    return true;
                }

                try {
                    minutes = std::stoi(minuteInput->getText().c_str());
                }
                catch (std::exception &e) {
                    LOG_ERROR("EventTimeItem::applyInputCallbacks minutes: %s", e.what());
                    return true;
                }

                if (mode24H && hours > style::window::calendar::time::max_hour_24H_mode) {
                    hourInput->setText("00");
                }
                else if (!mode24H && hours > style::window::calendar::time::max_hour_12H_mode) {
                    hourInput->setText("12");
                }
                if (minutes > style::window::calendar::time::max_minutes) {
                    minuteInput->setText("00");
                }

                autofill_hour = hours + 1;
                auto autofill_hour = hours + 1;
                if (this->descriptionLabel->getText() ==
                        utils::localize.get("app_calendar_new_edit_event_start").c_str() &&
                    !mode24H) {


@@ 188,29 161,8 @@ namespace gui
            }
        };

        hourInput->inputCallback = [&](Item &item, const InputEvent &event) {
            if (event.state != gui::InputEvent::State::keyReleasedShort) {
                return false;
            }
            if (hourInput->getText().length() > 1 && event.keyCode != gui::KeyCode::KEY_LEFT &&
                event.keyCode != gui::KeyCode::KEY_RIGHT && event.keyCode != gui::KeyCode::KEY_PND &&
                event.keyCode != gui::KeyCode::KEY_UP && event.keyCode != gui::KeyCode::KEY_DOWN) {
                return true;
            }
            return false;
        };

        minuteInput->inputCallback = [&](Item &item, const InputEvent &event) {
            if (event.state != gui::InputEvent::State::keyReleasedShort) {
                return false;
            }
            if (minuteInput->getText().length() > 1 && event.keyCode != gui::KeyCode::KEY_LEFT &&
                event.keyCode != gui::KeyCode::KEY_RIGHT && event.keyCode != gui::KeyCode::KEY_PND &&
                event.keyCode != gui::KeyCode::KEY_UP && event.keyCode != gui::KeyCode::KEY_DOWN) {
                return true;
            }
            return false;
        };
        onInputCallback(*hourInput);
        onInputCallback(*minuteInput);
    }

    void EventTimeItem::prepareForTimeMode()


@@ 249,16 201,10 @@ namespace gui
                return true;
            };

            mode12hInput->setMinimumSize(style::window::calendar::item::eventTime::time_input_12h_w,
                                         style::window::calendar::item::eventTime::height -
                                             style::window::calendar::item::eventTime::separator);
            mode12hInput->setMargins(gui::Margins(style::window::calendar::item::eventTime::separator, 0, 0, 0));
            hourInput->setMinimumSize(style::window::calendar::item::eventTime::time_input_12h_w,
                                      style::window::calendar::item::eventTime::height -
                                          style::window::calendar::item::eventTime::separator);
            minuteInput->setMinimumSize(style::window::calendar::item::eventTime::time_input_12h_w,
                                        style::window::calendar::item::eventTime::height -
                                            style::window::calendar::item::eventTime::separator);
            mode12hInput->setMinimumSize(timeItem::time_input_12h_w, timeItem::hBox_h);
            mode12hInput->setMargins(gui::Margins(timeItem::separator, 0, 0, 0));
            hourInput->setMinimumSize(timeItem::time_input_12h_w, timeItem::hBox_h);
            minuteInput->setMinimumSize(timeItem::time_input_12h_w, timeItem::hBox_h);

            onLoadCallback = [&](std::shared_ptr<EventsRecord> event) {
                if (this->descriptionLabel->getText() == utils::localize.get("app_calendar_new_edit_event_start")) {


@@ 289,22 235,18 @@ namespace gui
            };
        }
        else {
            hourInput->setMinimumSize(style::window::calendar::item::eventTime::time_input_24h_w,
                                      style::window::calendar::item::eventTime::height -
                                          style::window::calendar::item::eventTime::separator);
            minuteInput->setMinimumSize(style::window::calendar::item::eventTime::time_input_24h_w,
                                        style::window::calendar::item::eventTime::height -
                                            style::window::calendar::item::eventTime::separator);
            hourInput->setMinimumSize(timeItem::time_input_24h_w, timeItem::hBox_h);
            minuteInput->setMinimumSize(timeItem::time_input_24h_w, timeItem::hBox_h);

            onLoadCallback = [&](std::shared_ptr<EventsRecord> event) {
                if (this->descriptionLabel->getText() == utils::localize.get("app_calendar_new_edit_event_start")) {
                    auto start_time = TimePointToHourMinSec(event->date_from);
                    hourInput->setText(std::to_string(date::make12(start_time.hours()).count()));
                    hourInput->setText(std::to_string(start_time.hours().count()));
                    minuteInput->setText(std::to_string(start_time.minutes().count()));
                }
                else if (this->descriptionLabel->getText() == utils::localize.get("app_calendar_new_edit_event_end")) {
                    auto end_time = TimePointToHourMinSec(event->date_till);
                    hourInput->setText(std::to_string(date::make12(end_time.hours()).count()));
                    hourInput->setText(std::to_string(end_time.hours().count()));
                    minuteInput->setText(std::to_string(end_time.minutes().count()));
                }
            };


@@ 411,7 353,7 @@ namespace gui
                mode12hInput->setText(secondItem->mode12hInput->getText());
                minuteInput->setText(secondItem->minuteInput->getText());
            }
            hourInput->setText(std::to_string(hour));
            hourInput->setText(utils::to_string(hour));
        }
    }



@@ 440,4 382,51 @@ namespace gui
        return TimePointFromYearMonthDay(date) + hours + minutes;
    }

    void EventTimeItem::setTime(int keyValue, gui::Label &item)
    {
        auto itemValue = item.getText();
        auto key       = std::to_string(keyValue);
        if (itemValue == "0") {
            itemValue = key;
        }
        else {
            itemValue += key;
        }
        item.setText(itemValue);

        if (!utils::time::validateTime(hourInput->getText(), minuteInput->getText(), !mode24H)) {
            item.setText(key);
        }
    }

    void EventTimeItem::onInputCallback(gui::Label &timeInput)
    {
        timeInput.inputCallback = [&](Item &item, const InputEvent &event) {
            if (event.state != gui::InputEvent::State::keyReleasedShort) {
                return false;
            }
            if (auto value = gui::toNumeric(event.keyCode); value >= 0) {
                setTime(value, timeInput);
                return true;
            }
            else if (event.is(gui::KeyCode::KEY_PND)) {
                clearInput(timeInput);
                return true;
            }
            return false;
        };
    }

    void EventTimeItem::clearInput(gui::Label &timeInput)
    {
        if (auto length = timeInput.getText().length(); length > 0) {
            auto value = timeInput.getText();
            value.removeChar(length - 1);
            if (value.length() == 0) {
                value = "0";
            }
            timeInput.setText(value);
        }
    }

} /* namespace gui */

M module-apps/application-calendar/widgets/EventTimeItem.hpp => module-apps/application-calendar/widgets/EventTimeItem.hpp +5 -2
@@ 21,8 21,8 @@ namespace gui
        gui::HBox *hBox                = nullptr;
        gui::Label *colonLabel         = nullptr;
        gui::Label *descriptionLabel   = nullptr;
        gui::Text *hourInput           = nullptr;
        gui::Text *minuteInput         = nullptr;
        gui::Label *hourInput          = nullptr;
        gui::Label *minuteInput        = nullptr;
        gui::Label *mode12hInput       = nullptr;
        bool mode24H                   = false;
        gui::EventTimeItem *secondItem = nullptr;


@@ 33,6 33,9 @@ namespace gui

        void applyInputCallbacks();
        void prepareForTimeMode();
        void setTime(int keyValue, gui::Label &item);
        void onInputCallback(gui::Label &timeInput);
        void clearInput(gui::Label &timeInput);
        bool isPm(const std::string &text);
        void validateHour();
        void validateHourFor12hMode(std::chrono::hours start_hour,

M module-apps/application-calendar/widgets/NewEventCheckBoxWithLabel.cpp => module-apps/application-calendar/widgets/NewEventCheckBoxWithLabel.cpp +11 -7
@@ 9,15 9,16 @@ namespace gui

    NewEventCheckBoxWithLabel::NewEventCheckBoxWithLabel(app::Application *application,
                                                         const std::string &description,
                                                         bool checkIsOnLeftBarSide,
                                                         NewEditEventModel *model)
        : CheckBoxWithLabelItem(application, description, nullptr, checkIsOnLeftBarSide), model(model)
        : CheckBoxWithLabelItem(application, description, nullptr), model(model)
    {
        app = application;
        assert(app != nullptr);

        setMargins(gui::Margins(
            style::margins::small, style::window::calendar::item::checkBox::margin_top, 0, style::margins::small));
        setMargins(gui::Margins(style::margins::small,
                                style::window::calendar::item::checkBox::margin_top,
                                0,
                                style::window::calendar::leftMargin));
        applyCallbacks();
    }



@@ 66,9 67,7 @@ namespace gui
        };
        onSaveCallback = [&](std::shared_ptr<EventsRecord> event) {
            if (checkBox->isChecked()) {
                auto event_start = TimePointToHourMinSec(event->date_from);
                event->date_from =
                    event->date_from - event_start.hours() - event_start.minutes() - event_start.seconds();
                event->date_from = TimePointFromYearMonthDay(dateItem->getChosenDate());
                event->date_till = event->date_from +
                                   std::chrono::hours(style::window::calendar::time::max_hour_24H_mode) +
                                   std::chrono::minutes(style::window::calendar::time::max_minutes);


@@ 76,4 75,9 @@ namespace gui
        };
    }

    void NewEventCheckBoxWithLabel::setConnectionToDateItem(gui::EventDateItem *item)
    {
        dateItem = item;
    }

} /* namespace gui */

M module-apps/application-calendar/widgets/NewEventCheckBoxWithLabel.hpp => module-apps/application-calendar/widgets/NewEventCheckBoxWithLabel.hpp +3 -1
@@ 11,14 11,16 @@ namespace gui
    {
        NewEditEventModel *model = nullptr;
        app::Application *app    = nullptr;
        gui::EventDateItem *dateItem = nullptr;
        void applyCallbacks() override;

      public:
        NewEventCheckBoxWithLabel(app::Application *application,
                                  const std::string &description,
                                  bool checkIsOnLeftBarSide = false,
                                  NewEditEventModel *model  = nullptr);
        virtual ~NewEventCheckBoxWithLabel() override = default;

        void setConnectionToDateItem(gui::EventDateItem *item);
    };

} /* namespace gui */

M module-apps/application-calendar/widgets/RepeatAndReminderItem.cpp => module-apps/application-calendar/widgets/RepeatAndReminderItem.cpp +3 -2
@@ 3,9 3,10 @@

#include "RepeatAndReminderItem.hpp"
#include "application-calendar/widgets/CalendarStyle.hpp"
#include "application-calendar/ApplicationCalendar.hpp"
#include "application-alarm-clock/data/AlarmsData.hpp"
#include <Style.hpp>
#include <Utils.hpp>
#include <module-apps/application-calendar/ApplicationCalendar.hpp>

namespace gui
{


@@ 104,7 105,7 @@ namespace gui
        reminderTitle->setText(utils::localize.get("app_calendar_event_detail_reminder"));
        onLoadCallback = [&](std::shared_ptr<EventsRecord> event) {
            if (event->repeat > app::ApplicationCalendar::repeatOptions.size()) {
                repeat->setText("app_calendar_custom_repeat_title");
                repeat->setText(CustomRepeatValueParser(event->repeat).getWeekDaysText());
            }
            else {
                repeat->setText(utils::localize.get(

M module-apps/application-calendar/widgets/SeveralOptionsItem.cpp => module-apps/application-calendar/widgets/SeveralOptionsItem.cpp +45 -21
@@ 4,15 4,17 @@
#include "SeveralOptionsItem.hpp"
#include "InputEvent.hpp"
#include "application-calendar/widgets/CalendarStyle.hpp"
#include "module-apps/application-calendar/ApplicationCalendar.hpp"
#include "module-apps/application-calendar/data/CalendarData.hpp"
#include "module-apps/application-calendar/data/OptionParser.hpp"
#include "application-calendar/ApplicationCalendar.hpp"
#include "application-calendar/data/CalendarData.hpp"
#include "application-calendar/data/OptionParser.hpp"
#include "application-alarm-clock//data/AlarmsData.hpp"
#include <Style.hpp>
#include <Utils.hpp>
#include <module-db/Interface/EventsRecord.hpp>

namespace gui
{
    namespace optionsItem = style::window::calendar::item::severalOptions;

    SeveralOptionsItem::SeveralOptionsItem(app::Application *app,
                                           const std::string &description,


@@ 24,55 26,51 @@ namespace gui
        application = app;
        assert(app != nullptr);

        setMinimumSize(style::window::default_body_width, style::window::calendar::item::severalOptions::height);
        setMinimumSize(style::window::default_body_width, optionsItem::height);

        setEdges(RectangleEdge::Bottom);
        setPenWidth(style::window::default_border_rect_no_focus);
        setMargins(gui::Margins(style::margins::small, style::margins::huge / 2, 0, style::margins::huge / 2));
        setMargins(gui::Margins(style::window::calendar::leftMargin, style::margins::huge, 0, 0));

        vBox = new gui::VBox(this, 0, 0, 0, 0);
        vBox->setEdges(gui::RectangleEdge::None);
        vBox->activeItem = false;

        descriptionLabel = new gui::Label(vBox, 0, 0, 0, 0);
        descriptionLabel->setMinimumSize(style::window::default_body_width,
                                         style::window::calendar::item::severalOptions::label_h);
        descriptionLabel->setMinimumSize(style::window::default_body_width, optionsItem::label_h);
        descriptionLabel->setMargins(gui::Margins(0, 0, 0, optionsItem::margin));
        descriptionLabel->setEdges(gui::RectangleEdge::None);
        descriptionLabel->setAlignment(Alignment(gui::Alignment::Horizontal::Left, gui::Alignment::Vertical::Center));
        descriptionLabel->setAlignment(Alignment(gui::Alignment::Horizontal::Left, gui::Alignment::Vertical::Top));
        descriptionLabel->setFont(style::window::font::small);
        descriptionLabel->activeItem = false;
        descriptionLabel->setText(description);

        hBox = new gui::HBox(vBox, 0, 0, 0, 0);
        hBox->setMinimumSize(style::window::default_body_width,
                             style::window::calendar::item::severalOptions::height -
                                 style::window::calendar::item::severalOptions::label_h);
        hBox->setMinimumSize(style::window::default_body_width, optionsItem::hBox_h);
        hBox->setEdges(gui::RectangleEdge::None);
        hBox->activeItem = false;

        leftArrow = new gui::Image(hBox, 0, 0, 0, 0);
        leftArrow->setMinimumSize(style::window::calendar::item::severalOptions::arrow_w_h,
                                  style::window::calendar::item::severalOptions::arrow_w_h);
        leftArrow->setMinimumSize(optionsItem::arrow_w_h, optionsItem::arrow_w_h);
        leftArrow->setAlignment(Alignment(gui::Alignment::Horizontal::Left, gui::Alignment::Vertical::Center));
        leftArrow->activeItem = false;
        leftArrow->set("arrow_left");
        leftArrow->setVisible(false);

        optionLabel = new gui::Label(hBox, 0, 0, 0, 0);
        optionLabel->setMinimumSize(style::window::default_body_width -
                                        2 * style::window::calendar::item::severalOptions::arrow_w_h,
                                    style::window::calendar::item::severalOptions::height -
                                        style::window::calendar::item::severalOptions::label_h);
        optionLabel->setMinimumSize(optionsItem::option_w, optionsItem::hBox_h);
        optionLabel->setMargins(gui::Margins(optionsItem::arrow_w_h, 0, 0, 0));
        optionLabel->setEdges(gui::RectangleEdge::None);
        optionLabel->setAlignment(Alignment(gui::Alignment::Horizontal::Center, gui::Alignment::Vertical::Center));
        optionLabel->setFont(style::window::font::medium);
        optionLabel->activeItem = false;

        rightArrow = new gui::Image(hBox, 0, 0, 0, 0);
        rightArrow->setMinimumSize(style::window::calendar::item::severalOptions::arrow_w_h,
                                   style::window::calendar::item::severalOptions::arrow_w_h);
        rightArrow->setMinimumSize(optionsItem::arrow_w_h, optionsItem::arrow_w_h);
        rightArrow->setAlignment(Alignment(gui::Alignment::Horizontal::Right, gui::Alignment::Vertical::Center));
        rightArrow->activeItem = false;
        rightArrow->set("arrow_right");
        rightArrow->setVisible(false);

        prepareOptionsNames();
        applyCallbacks();


@@ 112,10 110,15 @@ namespace gui
                    descriptionLabel->getText() == utils::localize.get("app_calendar_event_detail_repeat")) {
                    bottomBarTemporaryMode(utils::localize.get("app_calendar_edit"));
                }
                optionLabel->setMargins(gui::Margins(0, 0, 0, 0));
            }
            else {
                optionLabel->setMargins(gui::Margins(optionsItem::arrow_w_h, 0, 0, 0));
                bottomBarRestoreFromTemporaryMode();
            }
            leftArrow->setVisible(item.focus);
            rightArrow->setVisible(item.focus);
            hBox->resizeItems();
            return true;
        };



@@ 166,9 169,13 @@ namespace gui

        onSaveCallback = [&](std::shared_ptr<EventsRecord> record) {
            if (descriptionLabel->getText() == utils::localize.get("app_calendar_event_detail_repeat")) {
                if (record->repeat < optionsNames.size() - 1 || actualVectorIndex < optionsNames.size() - 1) {
                if (record->repeat < optionsNames.size() - 1 && actualVectorIndex != optionsNames.size() - 1) {
                    record->repeat = actualVectorIndex;
                }
                else if (record->repeat == optionsNames.size() - 1 ||
                         optionsNames[optionsNames.size() - 1] == utils::localize.get("app_calendar_repeat_custom")) {
                    record->repeat = static_cast<uint32_t>(AlarmRepeat::never);
                }
            }
            else if (descriptionLabel->getText() == utils::localize.get("app_calendar_event_detail_reminder")) {
                record->reminder = static_cast<uint32_t>(reminderTimeOptions[actualVectorIndex]);


@@ 179,9 186,26 @@ namespace gui
            if (descriptionLabel->getText() == utils::localize.get("app_calendar_event_detail_repeat")) {
                if (event->repeat < optionsNames.size() - 1) {
                    actualVectorIndex = event->repeat;
                    if (event->repeat == static_cast<uint32_t>(Repeat::never)) {
                        optionsNames[optionsNames.size() - 1] = utils::localize.get("app_calendar_repeat_custom");
                    }
                    bottomBarRestoreFromTemporaryMode();
                }
                else {
                    actualVectorIndex = optionsNames.size() - 1;
                    auto parser = CustomRepeatValueParser(event->repeat);
                    if (parser.isCustomValueEveryday()) {
                        actualVectorIndex = static_cast<uint32_t>(Repeat::daily);
                        event->repeat     = actualVectorIndex;
                        bottomBarRestoreFromTemporaryMode();
                        optionsNames[optionsNames.size() - 1] = utils::localize.get("app_calendar_repeat_custom");
                    }
                    else {
                        actualVectorIndex                     = optionsNames.size() - 1;
                        optionsNames[optionsNames.size() - 1] = parser.getWeekDaysText();
                        if (this->focus) {
                            bottomBarTemporaryMode(utils::localize.get("app_calendar_edit"));
                        }
                    }
                }
                repeatOptionValue = event->repeat;
                optionLabel->setText(optionsNames[actualVectorIndex]);

M module-apps/application-calendar/widgets/TextWithLabelItem.cpp => module-apps/application-calendar/widgets/TextWithLabelItem.cpp +6 -3
@@ 14,7 14,10 @@ namespace gui
                                         std::function<void()> selectSpecialCharacter)
    {
        setMinimumSize(style::window::default_body_width, style::window::calendar::item::textWithLabel::height);
        setMargins(gui::Margins(style::margins::small, 0, 0, 0));
        setMargins(gui::Margins(style::window::calendar::leftMargin,
                                2 * style::window::calendar::leftMargin,
                                0,
                                1.5 * style::window::calendar::leftMargin));
        setEdges(RectangleEdge::None);
        bottomBarRestoreFromTemporaryMode();



@@ 26,7 29,7 @@ namespace gui
        descriptionLabel = new gui::Label(vBox, 0, 0, 0, 0);
        descriptionLabel->setMinimumSize(style::window::default_body_width,
                                         style::window::calendar::item::textWithLabel::description_h);
        descriptionLabel->setMargins(gui::Margins(0, style::margins::small, 0, 0));
        descriptionLabel->setMargins(gui::Margins(0, 0, 0, style::window::calendar::item::textWithLabel::margin));
        descriptionLabel->setEdges(gui::RectangleEdge::None);
        descriptionLabel->setAlignment(Alignment(gui::Alignment::Horizontal::Left, gui::Alignment::Vertical::Top));
        descriptionLabel->setFont(style::window::font::small);


@@ 37,7 40,7 @@ namespace gui
        textInput->setMinimumSize(style::window::default_body_width,
                                  style::window::calendar::item::textWithLabel::text_input_h);
        textInput->setEdges(gui::RectangleEdge::Bottom);
        textInput->setAlignment(gui::Alignment(gui::Alignment::Horizontal::Left, gui::Alignment::Vertical::Bottom));
        textInput->setAlignment(gui::Alignment(gui::Alignment::Horizontal::Left, gui::Alignment::Vertical::Center));
        textInput->setFont(style::window::font::medium);
        textInput->setInputMode(new InputMode(
            {InputMode::ABC, InputMode::abc, InputMode::digit},

M module-apps/application-calendar/windows/CustomRepeatWindow.cpp => module-apps/application-calendar/windows/CustomRepeatWindow.cpp +4 -11
@@ 29,7 29,9 @@ namespace gui
        AppWindow::buildInterface();

        bottomBar->setActive(gui::BottomBar::Side::RIGHT, true);
        bottomBar->setActive(gui::BottomBar::Side::CENTER, true);
        bottomBar->setText(gui::BottomBar::Side::RIGHT, utils::localize.get(style::strings::common::back));
        bottomBar->setText(gui::BottomBar::Side::CENTER, utils::localize.get(style::strings::common::save));

        setTitle(utils::localize.get("app_calendar_custom_repeat_title"));
        list = new gui::ListView(this,


@@ 60,15 62,11 @@ namespace gui
    bool CustomRepeatWindow::onInput(const InputEvent &inputEvent)
    {
        // check if any of the lower inheritance onInput methods catch the event
        if (Window::onInput(inputEvent)) {
        if (AppWindow::onInput(inputEvent)) {
            return true;
        }
        // process only if key is released
        if (!inputEvent.isShortPress())
            return false;

        switch (inputEvent.keyCode) {
        case KeyCode::KEY_RF: {
        if (inputEvent.isShortPress() && inputEvent.is(gui::KeyCode::KEY_ENTER)) {
            if (weekDaysOptData != nullptr) {
                auto isCheckedData = customRepeatModel->getIsCheckedData();
                uint32_t i         = 0;


@@ 83,11 81,6 @@ namespace gui
                return true;
            }
        }
        default:
            break;
        }

        return false;
    }

} /* namespace gui */

M module-apps/application-calendar/windows/NewEditEventWindow.cpp => module-apps/application-calendar/windows/NewEditEventWindow.cpp +1 -11
@@ 42,8 42,6 @@ namespace gui
    void NewEditEventWindow::onBeforeShow(gui::ShowMode mode, gui::SwitchData *data)
    {
        switch (eventAction) {
        case EventAction::None:
            break;
        case EventAction::Add: {
            setTitle(utils::localize.get("app_calendar_new_event_title"));
            break;


@@ 83,15 81,7 @@ namespace gui

        if (inputEvent.keyCode == gui::KeyCode::KEY_ENTER) {
            LOG_DEBUG("Save Event");
            bool edit = true;
            if (eventAction == EventAction::Edit) {
                edit = true;
            }
            else if (eventAction == EventAction::Add) {
                edit = false;
            }

            newEditEventModel->saveData(eventRecord, edit);
            newEditEventModel->saveData(eventRecord, eventAction);
            return true;
        }


M module-apps/application-calendar/windows/NewEditEventWindow.hpp => module-apps/application-calendar/windows/NewEditEventWindow.hpp +1 -7
@@ 21,16 21,10 @@ namespace gui
    class NewEditEventWindow : public gui::AppWindow
    {
      private:
        enum class EventAction
        {
            None,
            Add,
            Edit
        };
        std::shared_ptr<EventsRecord> eventRecord            = nullptr;
        gui::ListView *list                                  = nullptr;
        std::shared_ptr<NewEditEventModel> newEditEventModel = nullptr;
        EventAction eventAction                              = EventAction::None;
        EventAction eventAction                              = EventAction::Add;

      public:
        NewEditEventWindow(app::Application *app, std::string name);

M module-apps/windows/NoEvents.cpp => module-apps/windows/NoEvents.cpp +45 -1
@@ 23,10 23,28 @@ namespace style
        const inline uint32_t x = 48;
        const inline uint32_t y = 55;
    } // namespace cross

    namespace icon
    {
        constexpr inline auto x = 176;
        constexpr inline auto y = 195;
    } // namespace icon

    namespace text
    {
        constexpr inline auto x = 40;
        constexpr inline auto y = 333;
    } // namespace text
} // namespace style

NoEvents::NoEvents(app::Application *app, const std::string &name) : gui::Dialog(app, name)
{}
{
    arrow = new gui::Image(this, style::arrow::x, style::arrow::y, 0, 0, "arrow_left");
    cross = new gui::Image(this, style::cross::x, style::cross::y, 0, 0, "cross");

    icon->setPosition(style::icon::x, style::icon::y);
    text->setPosition(style::text::x, style::text::y);
}

void NoEvents::onBeforeShow(ShowMode mode, SwitchData *data)
{


@@ 41,4 59,30 @@ void NoEvents::onBeforeShow(ShowMode mode, SwitchData *data)
            return false;
        };
    }

    if (title->getText() == utils::localize.get("app_calendar_title_main")) {
        bottomBar->setActive(gui::BottomBar::Side::LEFT, true);
        bottomBar->setText(gui::BottomBar::Side::LEFT, utils::localize.get("app_calendar_bar_month"));
    }
}

bool NoEvents::onInput(const gui::InputEvent &inputEvent)
{
    if (inputEvent.isShortPress() && inputEvent.is(gui::KeyCode::KEY_RF) &&
        title->getText() == utils::localize.get("app_calendar_title_main")) {
        app::manager::Controller::switchBack(application);
        return true;
    }

    if (AppWindow::onInput(inputEvent)) {
        return true;
    }

    if (inputEvent.isShortPress() && inputEvent.is(gui::KeyCode::KEY_LF) &&
        title->getText() == utils::localize.get("app_calendar_title_main")) {
        application->switchWindow(gui::name::window::main_window);
        return true;
    }

    return false;
}

M module-apps/windows/NoEvents.hpp => module-apps/windows/NoEvents.hpp +4 -0
@@ 18,9 18,13 @@ namespace gui
{
    class NoEvents : public Dialog
    {
        gui::Image *arrow = nullptr;
        gui::Image *cross = nullptr;

      public:
        NoEvents(app::Application *app, const std::string &name);
        void onBeforeShow(ShowMode mode, SwitchData *data) override;
        bool onInput(const gui::InputEvent &inputEvent) override;
    };

}; // namespace gui

M module-utils/time/time_date_validation.cpp => module-utils/time/time_date_validation.cpp +1 -1
@@ 21,7 21,7 @@ namespace utils
            if (day < 1 || day > 31) {
                return false;
            }
            if ((day == 31) && (month = 2 || month == 4 || month == 6 || month == 9 || month == 11)) {
            if ((day == 31) && (month == 2 || month == 4 || month == 6 || month == 9 || month == 11)) {
                return false;
            }
            if (day == 30 && month == 2) {