~aleteoryx/muditaos

4c72152c6f1311d56b5862b7fd21042768cbe519 — mkamonMdt 5 years ago 3cc558b
[EGD-5597] Fix messages overflowing length

Current sms length is bound by 7*67 characters. This PR
enforce that limit on ApplicationMessages level.
Additionally PR solve:
 - corner case problem with invalid cursor position in TextBackup
 - EGD-4408 fix of label on desktop menuWindow
M enabled_unittests => enabled_unittests +2 -1
@@ 153,7 153,8 @@ TESTS_LIST["catch2-gui-text"]="
    handle text expand;
    handle newline;
    handle text block - moved cursor to end;
    Text backup and restore tests;
    Text backup overwrite and restore tests;
    Text backup with max width restricted - overwrite restore and add tests;
    Text addition bounds - text sings count restricted;
    Text addition bounds - text widget size restricted;
    Text addition bounds - text widget line size restricted;

M image/assets/lang/English.json => image/assets/lang/English.json +1 -1
@@ 246,7 246,7 @@
  "app_desktop_unread_messages": "<text>Unread <b>messages</b></text>",
  "app_desktop_low_battery_notification": "<text>low battery level - GSM off</text>",
  "app_desktop_missed_calls": "<text>Missed <b>calls</b></text>",
  "app_desktop_menu_phone": "PHONE",
  "app_desktop_menu_phone": "CALLS",
  "app_desktop_menu_contacts": "CONTACTS",
  "app_desktop_menu_messages": "MESSAGES",
  "app_desktop_menu_calendar": "CALENDAR",

M module-apps/application-messages/data/MessagesStyle.hpp => module-apps/application-messages/data/MessagesStyle.hpp +1 -0
@@ 51,6 51,7 @@ namespace style
            namespace text
            {
                inline constexpr uint32_t h = 43;
                inline constexpr uint32_t maxH = 320;
            }
            namespace messageLabel
            {

M module-apps/application-messages/widgets/SMSInputWidget.cpp => module-apps/application-messages/widgets/SMSInputWidget.cpp +2 -0
@@ 5,6 5,7 @@
#include "AppWindow.hpp"
#include "application-messages/data/MessagesStyle.hpp"
#include <module-apps/application-messages/ApplicationMessages.hpp>
#include <service-cellular/service-cellular/MessageConstants.hpp>

#include <Style.hpp>
#include <i18n/i18n.hpp>


@@ 33,6 34,7 @@ namespace gui
        inputText->setMaximumSize(style::messages::smsInput::default_input_w, style::messages::smsInput::max_input_h);
        inputText->setMinimumSize(style::messages::smsInput::default_input_w,
                                  style::messages::smsInput::default_input_h);
        inputText->setTextLimitType(gui::TextLimitType::MaxSignsCount, msgConstants::maxConcatenatedLen);
        inputText->setFont(style::window::font::medium);
        inputText->setPadding(Padding(0, 0, 0, style::messages::smsInput::bottom_padding));
        inputText->setPenFocusWidth(style::window::default_border_focus_w);

M module-apps/application-messages/windows/NewMessage.cpp => module-apps/application-messages/windows/NewMessage.cpp +6 -2
@@ 18,6 18,8 @@
#include <module-db/queries/messages/threads/QueryThreadGetByNumber.hpp>
#include <module-db/queries/messages/sms/QuerySMSGetLastByThreadID.hpp>

#include <service-cellular/service-cellular/MessageConstants.hpp>

#include <cassert>

namespace gui


@@ 172,11 174,11 @@ namespace gui
    void NewMessageWindow::updateBottomBar()
    {
        if (getFocusItem() == recipient) {
            bottomBar->setActive(BottomBar::Side::LEFT, false);
            if (recipient->getText().empty()) {
                bottomBar->setText(BottomBar::Side::CENTER, utils::localize.get(style::strings::common::select));
                return;
            }
            bottomBar->setActive(BottomBar::Side::LEFT, false);
            bottomBar->setActive(BottomBar::Side::CENTER, false);
        }
    }


@@ 185,6 187,7 @@ namespace gui
    {
        namespace msgStyle = style::messages::newMessage;
        AppWindow::buildInterface();
        bottomBar->setText(BottomBar::Side::LEFT, utils::localize.get(style::strings::common::options));
        bottomBar->setText(BottomBar::Side::RIGHT, utils::localize.get(style::strings::common::back));

        setTitle(utils::localize.get("sms_title_message"));


@@ 248,7 251,8 @@ namespace gui
        labelMessage->setAlignment(Alignment(gui::Alignment::Horizontal::Left, gui::Alignment::Vertical::Bottom));

        message = new gui::Text(nullptr, 0, 0, body->getWidth(), msgStyle::text::h, "", ExpandMode::Up);
        message->setMaximumSize(body->getWidth(), body->getHeight());
        message->setMaximumSize(body->getWidth(), msgStyle::text::maxH);
        message->setTextLimitType(gui::TextLimitType::MaxSignsCount, msgConstants::maxConcatenatedLen);
        message->setEdges(gui::RectangleEdge::Bottom);
        message->setInputMode(new InputMode(
            {InputMode::ABC, InputMode::abc, InputMode::digit},

M module-gui/gui/widgets/Text.cpp => module-gui/gui/widgets/Text.cpp +1 -1
@@ 907,7 907,7 @@ namespace gui
    TextBackup Text::backupText() const
    {
        return TextBackup{std::list<TextBlock>(document->getBlocks().begin(), document->getBlocks().end()),
                          cursor->getOnScreenPosition()};
                          cursor->getAbsolutePosition()};
    }

    void Text::restoreFrom(const TextBackup &backup)

M module-gui/gui/widgets/TextCursor.cpp => module-gui/gui/widgets/TextCursor.cpp +14 -0
@@ 216,6 216,20 @@ namespace gui
        return false;
    }

    auto TextCursor::getAbsolutePosition() const -> unsigned int
    {
        auto pos     = 0U;
        auto blockNo = 0U;
        for (const auto &block : document->getBlocks()) {
            if (blockNo == getBlockNumber()) {
                break;
            }
            pos += block.length();
            blockNo++;
        }
        return pos + BlockCursor::getPosition();
    }

} // namespace gui

const char *c_str(enum gui::TextCursor::Move what)

M module-gui/gui/widgets/TextCursor.hpp => module-gui/gui/widgets/TextCursor.hpp +1 -0
@@ 67,6 67,7 @@ namespace gui
        {
            return onScreenPosition;
        }
        [[nodiscard]] auto getAbsolutePosition() const -> unsigned int;
    };
} // namespace gui


M module-gui/test/test-catch-text/test-gui-Text.cpp => module-gui/test/test-catch-text/test-gui-Text.cpp +137 -7
@@ 89,7 89,12 @@ namespace gui

        [[nodiscard]] auto getCursorPosition()
        {
            return cursor->getOnScreenPosition();
            return cursor->getAbsolutePosition();
        }

        void setExpandMode(ExpandMode expandMode)
        {
            this->expandMode = expandMode;
        }
    };
} // namespace gui


@@ 266,13 271,13 @@ TEST_CASE("handle text block - moved cursor to end")
    REQUIRE(text.getText() == test_text);
}

TEST_CASE("Text backup and restore tests")
TEST_CASE("Text backup overwrite and restore tests")
{
    std::string testStringOneLine   = "Test String ";
    std::string testStringTwoLines  = "Test String 1 \n Test String 2";
    std::string overwriteTestString = "Overwrite test String";
    const std::string testStringOneLine   = "Test String ";
    const std::string testStringTwoLines  = "Test String 1 \n Test String 2";
    const std::string overwriteTestString = "Overwrite test String";

    SECTION("Backup one line text with moved cursor, overwrite text and restore")
    SECTION("Backup one line text with moved cursor")
    {
        mockup::fontManager();
        auto text = std::make_unique<gui::TestText>();


@@ 298,7 303,7 @@ TEST_CASE("Text backup and restore tests")
        REQUIRE(text->getCursorPosition() == testStringOneLine.length() - cursorMoveN);
    }

    SECTION("Backup two line text with moved cursor, overwrite text and restore")
    SECTION("Backup two line text with moved cursor")
    {
        mockup::fontManager();
        auto text = std::make_unique<gui::TestText>();


@@ 325,6 330,131 @@ TEST_CASE("Text backup and restore tests")
    }
}

TEST_CASE("Text backup with max width restricted - overwrite restore and add tests")
{
    const std::string testStringOneLine   = "Test String ";
    const std::string testStringTwoLines  = "Test String 1 \n Test String 2";
    const std::string overwriteTestString = "Overwrite test String";
    const std::string toAppendString1     = "Some text1";
    const std::string toAppendString2     = "Some text2";

    auto &fontManager = mockup::fontManager();
    auto font         = fontManager.getFont("gt_pressura_light_27");
    gui::TestText text;
    text.setFont(font);
    const auto textMaxHeight = 47;

    SECTION("Backup single line text")
    {
        const std::string expectedString1 = testStringOneLine + toAppendString1;
        const std::string expectedString2 = testStringOneLine + toAppendString1 + toAppendString2;
        text.setMaximumSize(font->getPixelWidth(testStringOneLine), textMaxHeight);

        text.setText(testStringOneLine);
        text.addText(toAppendString1);
        REQUIRE(text.getCursorPosition() == expectedString1.length());

        auto backup = text.backupText();

        REQUIRE(backup.document.getText() == text.getText());
        REQUIRE(backup.document.getText().length() == text.getText().length());
        REQUIRE(backup.cursorPos == text.getCursorPosition());

        text.setText(overwriteTestString);
        REQUIRE(text.getText() != expectedString1);

        text.restoreFrom(backup);
        text.addText(toAppendString2);

        REQUIRE(text.getText() == expectedString2);
        REQUIRE(text.getCursorPosition() == expectedString2.length());
    }

    SECTION("Backup single line text with moved cursor")
    {
        const std::string expectedString1 = testStringOneLine + toAppendString1;
        const std::string expectedString2 = testStringOneLine + toAppendString2 + toAppendString1;
        text.setMaximumSize(font->getPixelWidth(testStringOneLine), textMaxHeight);

        text.setText(testStringOneLine);
        text.addText(toAppendString1);

        const unsigned int cursorMoveN = toAppendString1.length();
        text.moveCursor(gui::NavigationDirection::LEFT, cursorMoveN);
        REQUIRE(text.getCursorPosition() == expectedString1.length() - cursorMoveN);

        auto backup = text.backupText();

        REQUIRE(backup.document.getText() == text.getText());
        REQUIRE(backup.document.getText().length() == text.getText().length());
        REQUIRE(backup.cursorPos == text.getCursorPosition());

        text.setText(overwriteTestString);
        REQUIRE(text.getText() != expectedString1);

        text.restoreFrom(backup);
        text.addText(toAppendString2);

        REQUIRE(text.getText() == expectedString2);
        REQUIRE(text.getCursorPosition() == testStringOneLine.length() + toAppendString2.length());
    }

    SECTION("Backup multi line text")
    {
        const std::string expectedString1 = testStringTwoLines + toAppendString1;
        const std::string expectedString2 = testStringTwoLines + toAppendString1 + toAppendString2;
        text.setMaximumSize(font->getPixelWidth(testStringTwoLines), textMaxHeight);

        text.setText(testStringTwoLines);
        text.addText(toAppendString1);
        REQUIRE(text.getCursorPosition() == expectedString1.length());

        auto backup = text.backupText();

        REQUIRE(backup.document.getText() == text.getText());
        REQUIRE(backup.document.getText().length() == text.getText().length());
        REQUIRE(backup.cursorPos == text.getCursorPosition());

        text.setText(overwriteTestString);
        REQUIRE(text.getText() != expectedString1);

        text.restoreFrom(backup);
        text.addText(toAppendString2);

        REQUIRE(text.getText() == expectedString2);
        REQUIRE(text.getCursorPosition() == expectedString2.length());
    }

    SECTION("Backup multi line text with moved cursor")
    {
        const std::string expectedString1 = testStringTwoLines + toAppendString1;
        const std::string expectedString2 = testStringTwoLines + toAppendString2 + toAppendString1;
        text.setMaximumSize(font->getPixelWidth(testStringTwoLines), textMaxHeight);

        text.setText(testStringTwoLines);
        text.addText(toAppendString1);

        const unsigned int cursorMoveN = toAppendString1.length();
        text.moveCursor(gui::NavigationDirection::LEFT, cursorMoveN);
        REQUIRE(text.getCursorPosition() == expectedString1.length() - cursorMoveN);

        auto backup = text.backupText();

        REQUIRE(backup.document.getText() == text.getText());
        REQUIRE(backup.document.getText().length() == text.getText().length());
        REQUIRE(backup.cursorPos == text.getCursorPosition());

        text.setText(overwriteTestString);
        REQUIRE(text.getText() != expectedString1);

        text.restoreFrom(backup);
        text.addText(toAppendString2);

        REQUIRE(text.getText() == expectedString2);
        REQUIRE(text.getCursorPosition() == testStringTwoLines.length() + toAppendString2.length());
    }
}

TEST_CASE("Text addition bounds - text sings count restricted")
{
    std::string testStringOneLine  = "Test String 1";

M module-services/service-cellular/ServiceCellular.cpp => module-services/service-cellular/ServiceCellular.cpp +3 -2
@@ 9,6 9,7 @@
#include "service-cellular/SignalStrength.hpp"
#include "service-cellular/State.hpp"
#include "service-cellular/USSD.hpp"
#include "service-cellular/MessageConstants.hpp"

#include "SimCard.hpp"
#include "NetworkSettings.hpp"


@@ 1422,7 1423,7 @@ bool ServiceCellular::sendSMS(SMSRecord record)
    uint32_t textLen = record.body.length();

    auto commandTimeout                 = at::factory(at::AT::CMGS).getTimeout();
    constexpr uint32_t singleMessageLen = 67;
    constexpr uint32_t singleMessageLen = msgConstants::singleMessageMaxLen;
    bool result                         = false;
    auto channel                        = cmux->get(TS0710::Channel::Commands);
    auto receiver                       = record.number.getEntered();


@@ 1450,7 1451,7 @@ bool ServiceCellular::sendSMS(SMSRecord record)
        }
        // split text, and send concatenated messages
        else {
            const uint32_t maxConcatenatedCount = 7;
            const uint32_t maxConcatenatedCount = msgConstants::maxConcatenatedCount;
            uint32_t messagePartsCount          = textLen / singleMessageLen;
            if ((textLen % singleMessageLen) != 0) {
                messagePartsCount++;

A module-services/service-cellular/service-cellular/MessageConstants.hpp => module-services/service-cellular/service-cellular/MessageConstants.hpp +8 -0
@@ 0,0 1,8 @@
#pragma once

namespace msgConstants
{
    constexpr uint32_t singleMessageMaxLen  = 67;
    constexpr uint32_t maxConcatenatedCount = 7;
    constexpr uint32_t maxConcatenatedLen   = singleMessageMaxLen * maxConcatenatedCount;
} // namespace msgConstants
\ No newline at end of file