~aleteoryx/muditaos

1c18ac422b0f5f21de408a66610c1ac6bb15258e — rrandomsky 2 years ago f1f2a7c
[MOS-195] Phone number input style unification

Unification of input style for phone number. Now every time when the user will provide
a phone number in gui the right function key (RF key) will be work as CLEAR.
This means that if any number is in the phone number field, the RF key will remove
the last character. Otherwise it'll work as typical BACK button.
This changes also provide ability to add * and # sign to number.
M module-apps/application-messages/windows/NewMessage.cpp => module-apps/application-messages/windows/NewMessage.cpp +69 -18
@@ 46,14 46,40 @@ namespace gui
            state.reset();
        }

      private:
      protected:
        std::unique_ptr<gui::TextBackup> state;
    };

    class NewMessageWindow::RecipientMemento : public NewMessageWindow::MessageMemento
    {
      public:
        void setState(const gui::Text *currentState, const std::shared_ptr<ContactRecord> chosenContact)
        {
            if (chosenContact != nullptr && !chosenContact->numbers.empty()) {
                phoneNumberView = std::make_unique<utils::PhoneNumber::View>(chosenContact->numbers.at(0).number);
            }

            MessageMemento::setState(currentState);
        }

        void restoreState(gui::Text *currentState, utils::PhoneNumber::View *currentPhoneNumberView)
        {
            if (currentPhoneNumberView != nullptr && phoneNumberView != nullptr) {
                *currentPhoneNumberView = *phoneNumberView;
                phoneNumberView.reset();
            }

            MessageMemento::restoreState(currentState);
        }

      private:
        std::unique_ptr<utils::PhoneNumber::View> phoneNumberView;
    };

    std::unique_ptr<NewMessageWindow::MessageMemento> NewMessageWindow::mementoMessage =
        std::make_unique<NewMessageWindow::MessageMemento>();
    std::unique_ptr<NewMessageWindow::MessageMemento> NewMessageWindow::mementoRecipient =
        std::make_unique<NewMessageWindow::MessageMemento>();
    std::unique_ptr<NewMessageWindow::RecipientMemento> NewMessageWindow::mementoRecipient =
        std::make_unique<NewMessageWindow::RecipientMemento>();

    NewMessageWindow::NewMessageWindow(app::ApplicationCommon *app)
        : AppWindow(app, name::window::new_sms), app::AsyncCallbackReceiver{app}


@@ 74,8 100,10 @@ namespace gui

    void NewMessageWindow::onBeforeShow(ShowMode mode, SwitchData *data)
    {
        mementoMessage->restoreState(message);
        mementoRecipient->restoreState(recipient);
        restoreMessageAndRecipientFromMemo();
        if (!recipient->isEmpty()) {
            body->setFocusItem(message);
        }
        if (data == nullptr) {
            return;
        }


@@ 186,10 214,14 @@ namespace gui
            navBar->setActive(nav_bar::Side::Left, false);
            if (recipient->getText().empty()) {
                navBar->setText(nav_bar::Side::Center, utils::translate(style::strings::common::contacts));
                navBar->setText(nav_bar::Side::Right, utils::translate(style::strings::common::back));
                return;
            }
            navBar->setActive(nav_bar::Side::Center, false);
            navBar->setText(nav_bar::Side::Right, utils::translate("app_call_clear"));
            return;
        }
        navBar->setText(nav_bar::Side::Right, utils::translate(style::strings::common::back));
    }

    void NewMessageWindow::buildInterface()


@@ 231,15 263,15 @@ namespace gui
        };
        recipient->inputCallback = [this]([[maybe_unused]] Item &, const InputEvent &inputEvent) -> bool {
            if (contact != nullptr) {
                if (inputEvent.isShortRelease(KeyCode::KEY_PND)) {
                if (inputEvent.isShortRelease(KeyCode::KEY_RF)) {
                    recipient->clear();
                    return true;
                }
                if (inputEvent.isDigit()) {
                if (inputEvent.isDigit() || inputEvent.is(KeyCode::KEY_AST) || inputEvent.is(KeyCode::KEY_PND)) {
                    return true;
                }
            }
            if (inputEvent.isShortRelease(KeyCode::KEY_RF)) {
            if (inputEvent.isShortRelease(KeyCode::KEY_RF) && recipient->isEmpty()) {
                onClose(CloseReason::WindowSwitch);
            }
            return false;


@@ 288,6 320,7 @@ namespace gui
            return true;
        };
        message->focusChangedCallback = [=](Item &) -> bool {
            navBar->setText(nav_bar::Side::Right, utils::translate(style::strings::common::back));
            if (recipient->getText().empty()) {
                navBar->setActive(nav_bar::Side::Center, false);
            }


@@ 301,8 334,7 @@ namespace gui
            if (event.isShortRelease(KeyCode::KEY_LF)) {
                auto app = dynamic_cast<app::ApplicationMessages *>(application);
                assert(app != nullptr);
                mementoMessage->setState(message);
                mementoRecipient->setState(recipient);
                storeMessageAndRecipientInMemo();
                return app->newMessageOptions(getName(), message);
            }
            if (event.isShortRelease(KeyCode::KEY_RF)) {


@@ 312,7 344,8 @@ namespace gui
        };
        body->addWidget(message);
        body->addWidget(new Span(Axis::Y, body->getHeight()));
        message->setText(""); // to set actual size of Text
        recipient->setText(""); // to clean up before load from memo
        message->setText("");   // to clean up before load from memo

        body->setEdges(gui::RectangleEdge::None);
        body->setVisible(true);


@@ 322,14 355,8 @@ namespace gui

    void NewMessageWindow::onClose(CloseReason reason)
    {
        if (message->getText().empty()) {
            // Nothing to do if text is empty.
            return;
        }

        if (reason != CloseReason::ApplicationClose) {
            mementoMessage->setState(message);
            mementoRecipient->setState(recipient);
            storeMessageAndRecipientInMemo();
            message->clear();
            return;
        }


@@ 410,4 437,28 @@ namespace gui
        message->clear();
    }

    void NewMessageWindow::storeMessageAndRecipientInMemo()
    {
        mementoMessage->setState(message);
        mementoRecipient->setState(recipient, contact);
    }

    void NewMessageWindow::restoreMessageAndRecipientFromMemo()
    {
        mementoMessage->restoreState(message);
        mementoRecipient->restoreState(recipient, &phoneNumber);

        if (phoneNumber.getNonEmpty() == "") {
            return;
        }

        contact = DBServiceAPI::MatchContactByPhoneNumber(application, phoneNumber);
        if (!contact || contact->isTemporary()) {
            recipient->setText(phoneNumber.getFormatted());
        }
        else {
            recipient->setText(contact->getFormattedName());
        }
    }

} // namespace gui

M module-apps/application-messages/windows/NewMessage.hpp => module-apps/application-messages/windows/NewMessage.hpp +4 -1
@@ 50,7 50,10 @@ namespace gui
        /// MessageMemento shall be used whenever there is a need for temporary window switch in normal (uninterrupted)
        /// flow of new message preparation, such as using options or recipient selection.
        class MessageMemento;
        class RecipientMemento;
        static std::unique_ptr<MessageMemento> mementoMessage;
        static std::unique_ptr<MessageMemento> mementoRecipient;
        static std::unique_ptr<RecipientMemento> mementoRecipient;
        void storeMessageAndRecipientInMemo();
        void restoreMessageAndRecipientFromMemo();
    };
} /* namespace gui */

M module-apps/application-phonebook/models/NewContactModel.cpp => module-apps/application-phonebook/models/NewContactModel.cpp +39 -5
@@ 4,9 4,6 @@
#include "NewContactModel.hpp"

#include "apps-common/windows/AppWindow.hpp"
#include "application-phonebook/widgets/ContactListItem.hpp"
#include "application-phonebook/widgets/InputBoxWithLabelAndIconWidget.hpp"
#include "application-phonebook/widgets/InputLinesWithLabelWidget.hpp"
#include "application-phonebook/ApplicationPhonebook.hpp"

#include <messages/DialogMetadataMessage.hpp>


@@ 37,13 34,18 @@ auto NewContactModel::getItem(gui::Order order) -> gui::ListItem *

void NewContactModel::createData()
{
    constexpr auto navBarOptionsLabelSide = gui::nav_bar::Side::Left;
    auto app = application;
    constexpr auto navBarOptionsLabelSide     = gui::nav_bar::Side::Left;
    constexpr auto navBarClearOrBackLabelSide = gui::nav_bar::Side::Right;
    auto app                                  = application;

    internalData.push_back(new gui::InputLinesWithLabelWidget(
        phonebookInternals::ListItemName::FirstName,
        [app](const UTF8 &text, bool emptyOthers) { app->getCurrentWindow()->navBarTemporaryMode(text, emptyOthers); },
        [app]() { app->getCurrentWindow()->navBarRestoreFromTemporaryMode(); },
        [app, this](const UTF8 &text, bool isRFKeyFunctionAsClear) {
            app->getCurrentWindow()->setNavBarText(text, navBarClearOrBackLabelSide);
            isRFKeyForClearFunction = isRFKeyFunctionAsClear;
        },
        [app](const UTF8 &text, bool active) {
            app->getCurrentWindow()->setNavBarText(text, navBarOptionsLabelSide);
            app->getCurrentWindow()->setNavBarActive(navBarOptionsLabelSide, active);


@@ 58,6 60,10 @@ void NewContactModel::createData()
        phonebookInternals::ListItemName::SecondName,
        [app](const UTF8 &text, bool emptyOthers) { app->getCurrentWindow()->navBarTemporaryMode(text, emptyOthers); },
        [app]() { app->getCurrentWindow()->navBarRestoreFromTemporaryMode(); },
        [app, this](const UTF8 &text, bool isRFKeyFunctionAsClear) {
            app->getCurrentWindow()->setNavBarText(text, navBarClearOrBackLabelSide);
            isRFKeyForClearFunction = isRFKeyFunctionAsClear;
        },
        [app](const UTF8 &text, bool active) {
            app->getCurrentWindow()->setNavBarText(text, navBarOptionsLabelSide);
            app->getCurrentWindow()->setNavBarActive(navBarOptionsLabelSide, active);


@@ 72,6 78,10 @@ void NewContactModel::createData()
        phonebookInternals::ListItemName::Number,
        [app](const UTF8 &text, bool emptyOthers) { app->getCurrentWindow()->navBarTemporaryMode(text, emptyOthers); },
        [app]() { app->getCurrentWindow()->navBarRestoreFromTemporaryMode(); },
        [app, this](const UTF8 &text, bool isRFKeyFunctionAsClear) {
            app->getCurrentWindow()->setNavBarText(text, navBarClearOrBackLabelSide);
            isRFKeyForClearFunction = isRFKeyFunctionAsClear;
        },
        [app](const UTF8 &text, bool active) {
            app->getCurrentWindow()->setNavBarText(text, navBarOptionsLabelSide);
            app->getCurrentWindow()->setNavBarActive(navBarOptionsLabelSide, active);


@@ 86,6 96,10 @@ void NewContactModel::createData()
        phonebookInternals::ListItemName::SecondNumber,
        [app](const UTF8 &text, bool emptyOthers) { app->getCurrentWindow()->navBarTemporaryMode(text, emptyOthers); },
        [app]() { app->getCurrentWindow()->navBarRestoreFromTemporaryMode(); },
        [app, this](const UTF8 &text, bool isRFKeyFunctionAsClear) {
            app->getCurrentWindow()->setNavBarText(text, navBarClearOrBackLabelSide);
            isRFKeyForClearFunction = isRFKeyFunctionAsClear;
        },
        [app](const UTF8 &text, bool active) {
            app->getCurrentWindow()->setNavBarText(text, navBarOptionsLabelSide);
            app->getCurrentWindow()->setNavBarActive(navBarOptionsLabelSide, active);


@@ 100,6 114,10 @@ void NewContactModel::createData()
        phonebookInternals::ListItemName::Email,
        [app](const UTF8 &text, bool emptyOthers) { app->getCurrentWindow()->navBarTemporaryMode(text, emptyOthers); },
        [app]() { app->getCurrentWindow()->navBarRestoreFromTemporaryMode(); },
        [app, this](const UTF8 &text, bool isRFKeyFunctionAsClear) {
            app->getCurrentWindow()->setNavBarText(text, navBarClearOrBackLabelSide);
            isRFKeyForClearFunction = isRFKeyFunctionAsClear;
        },
        [app](const UTF8 &text, bool active) {
            app->getCurrentWindow()->setNavBarText(text, navBarOptionsLabelSide);
            app->getCurrentWindow()->setNavBarActive(navBarOptionsLabelSide, active);


@@ 129,6 147,10 @@ void NewContactModel::createData()
        phonebookInternals::ListItemName::Address,
        [app](const UTF8 &text, bool emptyOthers) { app->getCurrentWindow()->navBarTemporaryMode(text, emptyOthers); },
        [app]() { app->getCurrentWindow()->navBarRestoreFromTemporaryMode(); },
        [app, this](const UTF8 &text, bool isRFKeyFunctionAsClear) {
            app->getCurrentWindow()->setNavBarText(text, navBarClearOrBackLabelSide);
            isRFKeyForClearFunction = isRFKeyFunctionAsClear;
        },
        [app](const UTF8 &text, bool active) {
            app->getCurrentWindow()->setNavBarText(text, navBarOptionsLabelSide);
            app->getCurrentWindow()->setNavBarActive(navBarOptionsLabelSide, active);


@@ 144,6 166,10 @@ void NewContactModel::createData()
        phonebookInternals::ListItemName::Note,
        [app](const UTF8 &text, bool emptyOthers) { app->getCurrentWindow()->navBarTemporaryMode(text, emptyOthers); },
        [app]() { app->getCurrentWindow()->navBarRestoreFromTemporaryMode(); },
        [app, this](const UTF8 &text, bool isRFKeyFunctionAsClear) {
            app->getCurrentWindow()->setNavBarText(text, navBarClearOrBackLabelSide);
            isRFKeyForClearFunction = isRFKeyFunctionAsClear;
        },
        [app](const UTF8 &text, bool active) {
            app->getCurrentWindow()->setNavBarText(text, navBarOptionsLabelSide);
            app->getCurrentWindow()->setNavBarActive(navBarOptionsLabelSide, active);


@@ 238,6 264,10 @@ void NewContactModel::openTextOptions(gui::Text *text)
bool NewContactModel::isAnyUnsavedChange(std::shared_ptr<ContactRecord> contactRecord)
{
    for (const auto &item : internalData) {
        if (auto itemInputWiget = dynamic_cast<gui::InputLinesWithLabelWidget *>(item)) {

            itemInputWiget->inputText->isInputMode(InputMode::phone);
        }
        if (item->onCheckUnsavedChangeCallback) {
            if (item->onCheckUnsavedChangeCallback(contactRecord)) {
                return true;


@@ 246,3 276,7 @@ bool NewContactModel::isAnyUnsavedChange(std::shared_ptr<ContactRecord> contactR
    }
    return false; // there is no change between already provided data and saved ones
}
bool NewContactModel::isRightFunctionKeyForClearFunction()
{
    return isRFKeyForClearFunction;
}

M module-apps/application-phonebook/models/NewContactModel.hpp => module-apps/application-phonebook/models/NewContactModel.hpp +4 -0
@@ 5,6 5,8 @@

#include "application-phonebook/data/PhonebookItemData.hpp"
#include "application-phonebook/widgets/ContactListItem.hpp"
#include "application-phonebook/widgets/InputBoxWithLabelAndIconWidget.hpp"
#include "application-phonebook/widgets/InputLinesWithLabelWidget.hpp"
#include "InternalModel.hpp"
#include "Application.hpp"



@@ 16,6 18,7 @@ class NewContactModel : public app::InternalModel<gui::ContactListItem *>, publi
  private:
    app::ApplicationCommon *application        = nullptr;
    PhonebookItemData::RequestType requestType = PhonebookItemData::RequestType::Internal;
    bool isRFKeyForClearFunction               = false; // By default, is for BACK function

    void openTextOptions(gui::Text *text);



@@ 29,6 32,7 @@ class NewContactModel : public app::InternalModel<gui::ContactListItem *>, publi
    bool verifyData();
    bool emptyData();
    bool isAnyUnsavedChange(std::shared_ptr<ContactRecord> contactRecord);
    bool isRightFunctionKeyForClearFunction();
    [[nodiscard]] auto getRequestType() -> PhonebookItemData::RequestType;

    [[nodiscard]] auto requestRecordsCount() -> unsigned int override;

M module-apps/application-phonebook/widgets/InputBoxWithLabelAndIconWidget.cpp => module-apps/application-phonebook/widgets/InputBoxWithLabelAndIconWidget.cpp +4 -2
@@ 15,9 15,11 @@ namespace gui
    InputBoxWithLabelAndIconWidget::InputBoxWithLabelAndIconWidget(
        phonebookInternals::ListItemName listItemName,
        std::function<void(const UTF8 &)> navBarTemporaryMode,
        std::function<void()> navBarRestoreFromTemporaryMode)
        std::function<void()> navBarRestoreFromTemporaryMode,
        std::function<void(const UTF8 &text)> navBarSetRFKeyLabel)
        : listItemName(listItemName), navBarTemporaryMode(std::move(navBarTemporaryMode)),
          navBarRestoreFromTemporaryMode(std::move(navBarRestoreFromTemporaryMode))
          navBarRestoreFromTemporaryMode(std::move(navBarRestoreFromTemporaryMode)),
          navBarSetRFKeyLabel(std::move(navBarSetRFKeyLabel))
    {
        setMinimumSize(phonebookStyle::inputBoxWithLabelAndIconIWidget::w,
                       phonebookStyle::inputBoxWithLabelAndIconIWidget::h);

M module-apps/application-phonebook/widgets/InputBoxWithLabelAndIconWidget.hpp => module-apps/application-phonebook/widgets/InputBoxWithLabelAndIconWidget.hpp +4 -2
@@ 1,4 1,4 @@
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once


@@ 22,7 22,8 @@ namespace gui
      public:
        InputBoxWithLabelAndIconWidget(phonebookInternals::ListItemName listItemName,
                                       std::function<void(const UTF8 &text)> navBarTemporaryMode = nullptr,
                                       std::function<void()> navBarRestoreFromTemporaryMode      = nullptr);
                                       std::function<void()> navBarRestoreFromTemporaryMode      = nullptr,
                                       std::function<void(const UTF8 &text)> navBarSetRFKeyLabel = nullptr);
        ~InputBoxWithLabelAndIconWidget() override = default;
        gui::HBox *hBox                            = nullptr;
        gui::Label *inputBoxLabel                  = nullptr;


@@ 33,6 34,7 @@ namespace gui
      private:
        std::function<void(const UTF8 &text)> navBarTemporaryMode = nullptr;
        std::function<void()> navBarRestoreFromTemporaryMode      = nullptr;
        std::function<void(const UTF8 &text)> navBarSetRFKeyLabel = nullptr;

        void applyItemNameSpecificSettings();


M module-apps/application-phonebook/widgets/InputLinesWithLabelWidget.cpp => module-apps/application-phonebook/widgets/InputLinesWithLabelWidget.cpp +19 -3
@@ 14,14 14,15 @@ namespace gui
        phonebookInternals::ListItemName listItemName,
        const std::function<void(const UTF8 &text, bool emptyOthers)> &navBarTemporaryMode,
        const std::function<void()> &navBarRestoreFromTemporaryMode,
        const std::function<void(const UTF8 &text, bool isRFKeyFunctionAsClear)> &navBarSetRFKeyLabel,
        const std::function<void(const UTF8 &text, bool active)> &navBarSetOptionsLabel,
        const std::function<void()> &selectSpecialCharacter,
        const std::function<void(std::function<void()> restoreFunction)> &restoreInputMode,
        const std::function<void(Text *text)> &inputOptions,
        unsigned int lines)
        std::uint32_t lines)
        : listItemName(listItemName), navBarTemporaryMode(navBarTemporaryMode),
          navBarRestoreFromTemporaryMode(navBarRestoreFromTemporaryMode), navBarSetOptionsLabel(navBarSetOptionsLabel),
          inputOptions(inputOptions)
          navBarRestoreFromTemporaryMode(navBarRestoreFromTemporaryMode), navBarSetRFKeyLabel(navBarSetRFKeyLabel),
          navBarSetOptionsLabel(navBarSetOptionsLabel), inputOptions(inputOptions)
    {
        setMinimumSize(phonebookStyle::inputLinesWithLabelWidget::w,
                       phonebookStyle::inputLinesWithLabelWidget::title_label_h +


@@ 78,6 79,8 @@ namespace gui
                    const auto optionsLabelState = !inputText->isEmpty() || Clipboard::getInstance().hasData();
                    this->navBarSetOptionsLabel(utils::translate(style::strings::common::options), optionsLabelState);
                }

                setRightFunctionKayLabel();
            }
            else {
                inputText->setCursorStartPosition(CursorStartPosition::DocumentBegin);


@@ 106,6 109,8 @@ namespace gui
                }
            }

            setRightFunctionKayLabel();

            return result;
        };



@@ 114,6 119,7 @@ namespace gui
            return true;
        };

        applyItemNameSpecificSettings();
        setEdges(RectangleEdge::None);
    }



@@ 303,5 309,15 @@ namespace gui
            return contact->note != inputText->getText();
        };
    }
    void InputLinesWithLabelWidget::setRightFunctionKayLabel()
    {
        if (inputText != nullptr && inputText->isInputMode(InputMode::phone) && this->navBarSetRFKeyLabel &&
            !inputText->isEmpty()) {
            navBarSetRFKeyLabel(utils::translate(utils::translate("app_call_clear")), true);
        }
        else {
            navBarSetRFKeyLabel(utils::translate(style::strings::common::back), false);
        }
    }

} /* namespace gui */

M module-apps/application-phonebook/widgets/InputLinesWithLabelWidget.hpp => module-apps/application-phonebook/widgets/InputLinesWithLabelWidget.hpp +14 -11
@@ 18,13 18,14 @@ namespace gui
      public:
        explicit InputLinesWithLabelWidget(
            phonebookInternals::ListItemName listItemName,
            const std::function<void(const UTF8 &text, bool emptyOthers)> &navBarTemporaryMode = nullptr,
            const std::function<void()> &navBarRestoreFromTemporaryMode                        = nullptr,
            const std::function<void(const UTF8 &text, bool active)> &navBarSetOptionsLabel    = nullptr,
            const std::function<void()> &selectSpecialCharacter                                = nullptr,
            const std::function<void(std::function<void()> restoreFunction)> &restoreInputMode = nullptr,
            const std::function<void(Text *text)> &inputOptions                                = nullptr,
            unsigned int lines                                                                 = 1);
            const std::function<void(const UTF8 &text, bool emptyOthers)> &navBarTemporaryMode            = nullptr,
            const std::function<void()> &navBarRestoreFromTemporaryMode                                   = nullptr,
            const std::function<void(const UTF8 &text, bool isRFKeyFunctionAsClear)> &navBarSetRFKeyLabel = nullptr,
            const std::function<void(const UTF8 &text, bool active)> &navBarSetOptionsLabel               = nullptr,
            const std::function<void()> &selectSpecialCharacter                                           = nullptr,
            const std::function<void(std::function<void()> restoreFunction)> &restoreInputMode            = nullptr,
            const std::function<void(Text *text)> &inputOptions                                           = nullptr,
            std::uint32_t lines                                                                           = 1);

        VBox *vBox               = nullptr;
        Label *titleLabel        = nullptr;


@@ 33,11 34,13 @@ namespace gui
      private:
        phonebookInternals::ListItemName listItemName;
        void applyItemNameSpecificSettings();
        void setRightFunctionKayLabel();

        std::function<void(const UTF8 &text, bool emptyOthers)> navBarTemporaryMode = nullptr;
        std::function<void()> navBarRestoreFromTemporaryMode                        = nullptr;
        std::function<void(const UTF8 &text, bool active)> navBarSetOptionsLabel    = nullptr;
        std::function<void(Text *text)> inputOptions                                = nullptr;
        std::function<void(const UTF8 &text, bool emptyOthers)> navBarTemporaryMode            = nullptr;
        std::function<void()> navBarRestoreFromTemporaryMode                                   = nullptr;
        std::function<void(const UTF8 &text, bool isRFKeyFunctionAsClear)> navBarSetRFKeyLabel = nullptr;
        std::function<void(const UTF8 &text, bool active)> navBarSetOptionsLabel               = nullptr;
        std::function<void(Text *text)> inputOptions                                           = nullptr;

        void firstNameHandler();
        void secondNameHandler();

M module-apps/application-phonebook/windows/PhonebookNewContact.cpp => module-apps/application-phonebook/windows/PhonebookNewContact.cpp +1 -1
@@ 151,7 151,7 @@ namespace gui
            return true;
        }
        else if (!inputEvent.isShortRelease(KeyCode::KEY_RF) || !shouldCurrentAppBeIgnoredOnSwitchBack()) {
            if (isAnyUnsavedUserDataInWindow()) {
            if (!newContactModel->isRightFunctionKeyForClearFunction() && isAnyUnsavedUserDataInWindow()) {
                if (inputEvent.isShortRelease(gui::KeyCode::KEY_RF) || inputEvent.isLongRelease(gui::KeyCode::KEY_RF)) {
                    showDialogUnsavedChanges([this]() {
                        application->returnToPreviousWindow();

M module-gui/gui/widgets/text/Text.cpp => module-gui/gui/widgets/text/Text.cpp +38 -3
@@ 360,6 360,19 @@ namespace gui
        this->inputMode = mode;
    }

    bool Text::isInputMode(InputMode::Mode mode)
    {
        if (inputMode == nullptr) {
            LOG_WARN("Pointer to inputMode is set as nullptr");
            return false;
        }

        if (inputMode->is(mode)) {
            return true;
        }
        return false;
    }

    std::string Text::getInputModeKeyMap()
    {
        if (inputMode == nullptr) {


@@ 546,7 559,8 @@ namespace gui

    auto Text::handleRotateInputMode(const InputEvent &inputEvent) -> bool
    {
        if (inputMode != nullptr && inputEvent.isShortRelease(gui::KeyCode::KEY_AST)) {
        if (inputMode != nullptr && !inputMode->is(InputMode::phone) &&
            inputEvent.isShortRelease(gui::KeyCode::KEY_AST)) {
            inputMode->next();
            return true;
        }


@@ 572,6 586,9 @@ namespace gui

    auto Text::handleActivation(const InputEvent &inputEvent) -> bool
    {
        if (inputMode && inputMode->is(InputMode::phone)) {
            return false;
        }
        return inputEvent.isShortRelease(KeyCode::KEY_AST) && Rect::onActivated(nullptr);
    }



@@ 637,7 654,13 @@ namespace gui
        if (!isMode(EditMode::Edit)) {
            return false;
        }
        if (inputEvent.isShortRelease(removeKey)) {

        if (document->isEmpty() && inputMode->is(InputMode::phone)) {
            return false;
        }

        auto removeKeyCode = inputMode->is(InputMode::phone) ? removeKeyForPhone : removeKey;
        if (inputEvent.isShortRelease(removeKeyCode)) {

            setCursorStartPosition(CursorStartPosition::Offset);



@@ 655,7 678,9 @@ namespace gui
        if (!isMode(EditMode::Edit)) {
            return false;
        }
        if (inputEvent.isLongRelease(removeKey)) {

        auto removeKeyCode = inputMode->is(InputMode::phone) ? removeKeyForPhone : removeKey;
        if (inputEvent.isLongRelease(removeKeyCode)) {
            if (!document->isEmpty()) {
                removeFromCursor();
                return true;


@@ 1034,6 1059,16 @@ namespace gui
        return false;
    }

    bool Text::removeWholeText()
    {
        bool returnValue = false;
        while (!document->isEmpty()) {
            cursor->removeChar();
            returnValue = true;
        }
        return returnValue;
    }

    void Text::onTextChanged()
    {
        if (textChangedCallback) {

M module-gui/gui/widgets/text/Text.hpp => module-gui/gui/widgets/text/Text.hpp +4 -1
@@ 29,7 29,8 @@ namespace gui
        unsigned int cursorPos;
    };

    constexpr KeyCode removeKey = KeyCode::KEY_PND;
    constexpr KeyCode removeKey         = KeyCode::KEY_PND;
    constexpr KeyCode removeKeyForPhone = KeyCode::KEY_RF;

    ///  @brief Widget that holds multiple lines of text.
    ///


@@ 171,6 172,7 @@ namespace gui

        /// move ownership of mode ptr to Text
        void setInputMode(InputMode *&&mode);
        bool isInputMode(InputMode::Mode mode);
        std::string getInputModeKeyMap();
        InputMode::Mode detectInputMode();



@@ 209,6 211,7 @@ namespace gui

        bool addChar(std::uint32_t utf8);
        bool removeChar();
        bool removeWholeText();
        void onTextChanged();
        void setTextChangedCallback(TextChangedCallback &&callback);
    };

M pure_changelog.md => pure_changelog.md +1 -0
@@ 47,6 47,7 @@
* Fixed losing unsaved user data when tethering is switching on
* Fixed invalid elapsed time in music player after playing and pausing track from songs list view
* Fixed disappearing "Call" label in Phonebook app
* Fixed phone number input style unification

## [1.7.2 2023-07-28]