M image/assets/lang/Deutsch.json => image/assets/lang/Deutsch.json +3 -2
@@ 77,6 77,8 @@
"common_minutes_lower": "minuten",
"common_minute_short": "min",
"common_paused": "Pausiert",
+ "common_text_copy": "Text kopieren",
+ "common_text_paste": "Text einfügen",
"locale_12hour_min": "%I:%M %p",
"locale_12hour_min_short": "%I:%M",
"locale_24hour_min": "%H:%M",
@@ 164,8 166,6 @@
"app_options_contact_edit": "Kontakte ändern",
"app_notes_title_main": "Notizen",
"app_notes_edit_new_note": "Ändern/Neue Notiz",
- "app_notes_copy_text": "Text kopieren",
- "app_notes_copy_paste": "Text einfügen",
"app_notes_edit": "ÄNDERN",
"app_notes_edited": "Geändert",
"app_notes_delete_note": "Löschen",
@@ 547,6 547,7 @@
"app_phonebook_new_contact_address": "Adresse",
"app_phonebook_new_contact_note": "Notiz",
"app_phonebook_new_speed_dial_key": "Kurzwahltaste",
+ "app_phonebook_new_contact_invalid_number": "<text>Dieser Kontakt kann nicht gespeichert werden.<br></br>Die von Ihnen eingegebene Telefonnummer<br></br>hat ein ungültiges Format.</text>",
"app_phonebook_new_add_to_fav": "Zu Favoriten hinzufügen",
"app_phonebook_new_add_to_ice": "Zu ICE hinzufügen",
"app_phonebook_check": "AUSWÄHLEN",
M image/assets/lang/English.json => image/assets/lang/English.json +3 -2
@@ 80,6 80,8 @@
"common_minutes_lower": "minutes",
"common_minute_short": "min",
"common_paused": "Paused",
+ "common_text_copy": "Copy text",
+ "common_text_paste": "Paste text",
"locale_12hour_min": "%I:%M %p",
"locale_12hour_min_short": "%I:%M",
"locale_24hour_min": "%H:%M",
@@ 136,8 138,6 @@
"app_options_contact_edit": "Edit Contact",
"app_notes_title_main": "Notes",
"app_notes_edit_new_note": "Edit/New Note",
- "app_notes_copy_text": "Copy text",
- "app_notes_copy_paste": "Paste text",
"app_notes_edit": "EDIT",
"app_notes_edited": "Edited",
"app_notes_delete_note": "Delete",
@@ 523,6 523,7 @@
"app_phonebook_new_contact_address": "Address",
"app_phonebook_new_contact_note": "Note",
"app_phonebook_new_speed_dial_key": "Speed dial key",
+ "app_phonebook_new_contact_invalid_number": "<text>Cannot save this contact.<br></br>The phone number you entered <br></br>is in an invalid format.</text>",
"app_phonebook_new_add_to_fav": "Add to favourites",
"app_phonebook_new_add_to_ice": "Emergency Contact (ICE)",
"app_phonebook_check": "CHECK",
M image/assets/lang/Espanol.json => image/assets/lang/Espanol.json +3 -2
@@ 77,6 77,8 @@
"common_minutes_lower": "minutos",
"common_minute_short": "min",
"common_paused": "Pausado",
+ "common_text_copy": "Copiar texto",
+ "common_text_paste": "Pegar texto",
"locale_12hour_min": "%I:%M %p",
"locale_12hour_min_short": "%I:%M",
"locale_24hour_min": "%H:%M",
@@ 164,8 166,6 @@
"app_options_contact_edit": "Editar contacto",
"app_notes_title_main": "Notas",
"app_notes_edit_new_note": "Editar/Nueva nota",
- "app_notes_copy_text": "Copiar texto",
- "app_notes_copy_paste": "Pegar texto",
"app_notes_edit": "EDITAR",
"app_notes_edited": "Editado",
"app_notes_delete_note": "Eliminar",
@@ 547,6 547,7 @@
"app_phonebook_new_contact_address": "Dirección",
"app_phonebook_new_contact_note": "Nota",
"app_phonebook_new_speed_dial_key": "Tecla de marcación rápida",
+ "app_phonebook_new_contact_invalid_number": "<text>No se puede guardar este contacto.<br></br>El número de teléfono que ingresó <br></br>tiene un formato no válido.</text>",
"app_phonebook_new_add_to_fav": "Añadir a favoritos",
"app_phonebook_new_add_to_ice": "Añadir a contactos de emergencia",
"app_phonebook_check": "MARCAR",
M image/assets/lang/Francais.json => image/assets/lang/Francais.json +3 -2
@@ 77,6 77,8 @@
"common_minutes_lower": "minutes",
"common_minute_short": "min",
"common_paused": "En pause",
+ "common_text_copy": "Copier le texte",
+ "common_text_paste": "Coller le texte",
"locale_12hour_min": "%I:%M %p",
"locale_12hour_min_short": "%I:%M",
"locale_24hour_min": "%H:%M",
@@ 133,8 135,6 @@
"app_options_contact_edit": "Modifier le contact",
"app_notes_title_main": "Notes",
"app_notes_edit_new_note": "Modifier/ajouter une note",
- "app_notes_copy_text": "Copier le texte",
- "app_notes_copy_paste": "Coller le texte",
"app_notes_edit": "MODIFIER",
"app_notes_edited": "Modifiée",
"app_notes_delete_note": "Supprimer",
@@ 514,6 514,7 @@
"app_phonebook_new_contact_address": "Adresse",
"app_phonebook_new_contact_note": "Note",
"app_phonebook_new_speed_dial_key": "Touche de numérotation rapide",
+ "app_phonebook_new_contact_invalid_number": "<text>Impossible d'enregistrer ce contact.<br></br>Le numéro de téléphone que vous avez entré <br></br>est dans un format invalide.</text>",
"app_phonebook_new_add_to_fav": "Ajouter aux favoris",
"app_phonebook_new_add_to_ice": "Ajouter aux contacts d'urgence",
"app_phonebook_check": "COCHER",
M image/assets/lang/Polski.json => image/assets/lang/Polski.json +3 -2
@@ 77,6 77,8 @@
"common_minutes_lower": "minuty",
"common_minute_short": "min",
"common_paused": "Pauza",
+ "common_text_copy": "Kopiuj tekst",
+ "common_text_paste": "Wklej tekst",
"locale_12hour_min": "%I:%M %p",
"locale_12hour_min_short": "%I:%M",
"locale_24hour_min": "%H:%M",
@@ 168,8 170,6 @@
"app_options_contact_edit": "Edytuj kontakt",
"app_notes_title_main": "Notatki",
"app_notes_edit_new_note": "Edytuj / Dodaj notatkę",
- "app_notes_copy_text": "Kopiuj tekst",
- "app_notes_copy_paste": "Wklej tekst",
"app_notes_edit": "EDYTUJ",
"app_notes_edited": "Edytowano",
"app_notes_delete_note": "Usuń",
@@ 557,6 557,7 @@
"app_phonebook_new_contact_address": "Adres",
"app_phonebook_new_contact_note": "Notatka",
"app_phonebook_new_speed_dial_key": "Klawisz szybkiego wybierania",
+ "app_phonebook_new_contact_invalid_number": "<text>Nie można zapisać tego kontaktu.<br></br>Wprowadzony numer telefonu<br></br>ma nieprawidłowy format.</text>",
"app_phonebook_new_add_to_ice": "Dodaj do kontaktów ICE",
"app_phonebook_check": "ZAZNACZ",
"app_phonebook_uncheck": "ODZNACZ",
M image/assets/lang/Svenska.json => image/assets/lang/Svenska.json +3 -2
@@ 65,6 65,8 @@
"common_today": "Idag",
"common_results_prefix": "Resultat: ",
"common_search": "SÖK",
+ "common_text_copy": "Kopiera text",
+ "common_text_paste": "Klistra in text",
"locale_12hour_min": "%I:%M %p",
"locale_12hour_min_short": "%I:%M",
"locale_24hour_min": "%H:%M",
@@ 118,8 120,6 @@
"app_options_contact_edit": "Redigera kontakt",
"app_notes_title_main": "Anteckningar",
"app_notes_edit_new_note": "Redigera/Skapa anteckning",
- "app_notes_copy_text": "Kopiera text",
- "app_notes_copy_paste": "Klistra in text",
"app_notes_edit": "REDIGERA",
"app_notes_edited": "Redigerad",
"app_notes_delete_note": "Radera",
@@ 455,6 455,7 @@
"app_phonebook_new_contact_address": "Adress",
"app_phonebook_new_contact_note": "Anteckning",
"app_phonebook_new_speed_dial_key": "Förvalsnummer",
+ "app_phonebook_new_contact_invalid_number": "<text>Det går inte att spara den här kontakten.<br></br>Telefonnumret du angav<br></br>är i ett ogiltigt format.</text>",
"app_phonebook_new_add_to_fav": "Lägg till bland favoriter",
"app_phonebook_new_add_to_ice": "Lägg till bland ICE (kontakter i fall av olycka)",
"app_phonebook_check": "MARKERA",
M module-apps/application-messages/windows/OptionsMessages.cpp => module-apps/application-messages/windows/OptionsMessages.cpp +1 -1
@@ 78,7 78,7 @@ std::list<gui::Option> newMessageWindowOptions(app::ApplicationMessages *app,
if (Clipboard::getInstance().gotData()) {
options.emplace_back(utils::translate("sms_paste"), [=](gui::Item &item) {
- text->addText(Clipboard::getInstance().paste());
+ text->addText(Clipboard::getInstance().paste(), gui::AdditionType::perBlock);
app->returnToPreviousWindow();
return true;
});
M module-apps/application-notes/windows/NotesOptions.cpp => module-apps/application-notes/windows/NotesOptions.cpp +4 -4
@@ 66,7 66,7 @@ namespace app::notes
{
std::list<gui::Option> options;
addOption(
- {"app_notes_copy_text"},
+ {"common_text_copy"},
[application, textWidget](gui::Item &item) {
if (textWidget != nullptr) {
Clipboard::getInstance().copy(textWidget->getText());
@@ 91,7 91,7 @@ namespace app::notes
{
std::list<gui::Option> options;
addOption(
- {"app_notes_copy_text"},
+ {"common_text_copy"},
[application, textWidget](gui::Item &item) {
if (textWidget != nullptr) {
Clipboard::getInstance().copy(textWidget->getText());
@@ 101,10 101,10 @@ namespace app::notes
},
options);
addOption(
- {"app_notes_copy_paste"},
+ {"common_text_paste"},
[application, textWidget](gui::Item &item) {
if (textWidget != nullptr) {
- textWidget->addText(Clipboard::getInstance().paste());
+ textWidget->addText(Clipboard::getInstance().paste(), gui::AdditionType::perBlock);
}
application->returnToPreviousWindow();
return true;
M module-apps/application-phonebook/ApplicationPhonebook.cpp => module-apps/application-phonebook/ApplicationPhonebook.cpp +4 -1
@@ 13,6 13,7 @@
#include "windows/PhonebookSearch.hpp"
#include "windows/PhonebookSearchResults.hpp"
#include "windows/PhonebookIceContacts.hpp"
+#include "windows/PhonebookInputOptions.hpp"
#include <service-appmgr/Controller.hpp>
#include <service-db/QueryMessage.hpp>
#include <service-db/DBNotificationMessage.hpp>
@@ 129,7 130,9 @@ namespace app
windowsFactory.attach(gui::window::name::ice_contacts, [](ApplicationCommon *app, const std::string &name) {
return std::make_unique<gui::PhonebookIceContacts>(app);
});
-
+ windowsFactory.attach(gui::window::name::input_options, [](ApplicationCommon *app, const std::string &name) {
+ return std::make_unique<gui::PhonebookInputOptions>(app, name);
+ });
windowsFactory.attach(gui::window::name::new_contact, [](ApplicationCommon *app, const std::string &name) {
return std::make_unique<gui::PhonebookNewContact>(app);
});
M module-apps/application-phonebook/CMakeLists.txt => module-apps/application-phonebook/CMakeLists.txt +3 -2
@@ 21,13 21,14 @@ target_sources(application-phonebook
widgets/ContactFlagsWidget.cpp
widgets/InformationWidget.cpp
widgets/InputBoxWithLabelAndIconWidget.cpp
- widgets/InputLinesWithLabelIWidget.cpp
+ widgets/InputLinesWithLabelWidget.cpp
widgets/OutputLinesTextWithLabelWidget.cpp
widgets/PhonebookItem.cpp
widgets/PhonebookListView.cpp
windows/PhonebookContactDetails.cpp
windows/PhonebookContactOptions.cpp
windows/PhonebookIceContacts.cpp
+ windows/PhonebookInputOptions.cpp
windows/PhonebookMainWindow.cpp
windows/PhonebookNamecardOptions.cpp
windows/PhonebookNewContact.cpp
@@ 41,7 42,7 @@ target_sources(application-phonebook
widgets/ContactListItem.hpp
widgets/InformationWidget.hpp
widgets/InputBoxWithLabelAndIconWidget.hpp
- widgets/InputLinesWithLabelIWidget.hpp
+ widgets/InputLinesWithLabelWidget.hpp
widgets/OutputLinesTextWithLabelWidget.hpp
widgets/PhonebookItem.hpp
widgets/PhonebookListView.hpp
M module-apps/application-phonebook/data/PhonebookItemData.hpp => module-apps/application-phonebook/data/PhonebookItemData.hpp +15 -0
@@ 60,3 60,18 @@ class PhonebookSearchRequest : public gui::SwitchData
PhonebookSearchRequest() = default;
std::shared_ptr<ContactRecord> result = nullptr;
};
+
+class PhonebookInputOptionData : public gui::SwitchData
+{
+ private:
+ gui::Text *inputText;
+
+ public:
+ explicit PhonebookInputOptionData(gui::Text *inputText) : inputText(inputText)
+ {}
+
+ gui::Text *getInputText()
+ {
+ return inputText;
+ }
+};
M module-apps/application-phonebook/data/PhonebookStyle.hpp => module-apps/application-phonebook/data/PhonebookStyle.hpp +4 -0
@@ 112,6 112,10 @@ namespace phonebookStyle
inline constexpr uint32_t span_size = 8;
inline constexpr uint32_t line_spacing = 15;
inline constexpr int32_t underline_padding = 4;
+
+ inline constexpr auto minimum_signs_limit = 31U;
+ inline constexpr auto medium_signs_limit = 40U;
+ inline constexpr auto max_signs_limit = 200U;
} // namespace inputLinesWithLabelWidget
namespace outputLinesTextWithLabelWidget
M module-apps/application-phonebook/include/application-phonebook/ApplicationPhonebook.hpp => module-apps/application-phonebook/include/application-phonebook/ApplicationPhonebook.hpp +1 -0
@@ 12,6 12,7 @@ namespace gui::window::name
inline constexpr auto contact = "Contact";
inline constexpr auto contact_options = "Options";
inline constexpr auto namecard_options = "Namecard Options";
+ inline constexpr auto input_options = "Input Options";
inline constexpr auto new_contact = "New";
inline constexpr auto search = "Search";
inline constexpr auto search_results = "SearchResults";
M module-apps/application-phonebook/models/NewContactModel.cpp => module-apps/application-phonebook/models/NewContactModel.cpp +58 -31
@@ 3,14 3,12 @@
#include "NewContactModel.hpp"
-#include "AppWindow.hpp"
#include "application-phonebook/widgets/ContactListItem.hpp"
#include "application-phonebook/widgets/InputBoxWithLabelAndIconWidget.hpp"
-#include "application-phonebook/widgets/InputLinesWithLabelIWidget.hpp"
+#include "application-phonebook/widgets/InputLinesWithLabelWidget.hpp"
+#include "application-phonebook/ApplicationPhonebook.hpp"
-#include <ListView.hpp>
-#include <time/ScopedTime.hpp>
-#include <NavBar.hpp>
+#include <messages/DialogMetadataMessage.hpp>
NewContactModel::NewContactModel(app::ApplicationCommon *app) : application(app)
{}
@@ 40,40 38,40 @@ void NewContactModel::createData()
{
auto app = application;
- internalData.push_back(new gui::InputLinesWithLabelIWidget(
+ internalData.push_back(new gui::InputLinesWithLabelWidget(
phonebookInternals::ListItemName::FirstName,
- [app](const UTF8 &text) { app->getCurrentWindow()->navBarTemporaryMode(text); },
+ [app](const UTF8 &text, bool emptyOthers) { app->getCurrentWindow()->navBarTemporaryMode(text, emptyOthers); },
[app]() { app->getCurrentWindow()->navBarRestoreFromTemporaryMode(); },
[app]() { app->getCurrentWindow()->selectSpecialCharacter(); },
- [this]() { this->ContactDataChanged(); }));
+ [&](gui::Text *text) { openTextOptions(text); }));
- internalData.push_back(new gui::InputLinesWithLabelIWidget(
+ internalData.push_back(new gui::InputLinesWithLabelWidget(
phonebookInternals::ListItemName::SecondName,
- [app](const UTF8 &text) { app->getCurrentWindow()->navBarTemporaryMode(text); },
+ [app](const UTF8 &text, bool emptyOthers) { app->getCurrentWindow()->navBarTemporaryMode(text, emptyOthers); },
[app]() { app->getCurrentWindow()->navBarRestoreFromTemporaryMode(); },
[app]() { app->getCurrentWindow()->selectSpecialCharacter(); },
- [this]() { this->ContactDataChanged(); }));
+ [&](gui::Text *text) { openTextOptions(text); }));
- internalData.push_back(new gui::InputLinesWithLabelIWidget(
+ internalData.push_back(new gui::InputLinesWithLabelWidget(
phonebookInternals::ListItemName::Number,
- [app](const UTF8 &text) { app->getCurrentWindow()->navBarTemporaryMode(text); },
+ [app](const UTF8 &text, bool emptyOthers) { app->getCurrentWindow()->navBarTemporaryMode(text, emptyOthers); },
[app]() { app->getCurrentWindow()->navBarRestoreFromTemporaryMode(); },
[app]() { app->getCurrentWindow()->selectSpecialCharacter(); },
- [this]() { this->ContactDataChanged(); }));
+ [&](gui::Text *text) { openTextOptions(text); }));
- internalData.push_back(new gui::InputLinesWithLabelIWidget(
+ internalData.push_back(new gui::InputLinesWithLabelWidget(
phonebookInternals::ListItemName::SecondNumber,
- [app](const UTF8 &text) { app->getCurrentWindow()->navBarTemporaryMode(text); },
+ [app](const UTF8 &text, bool emptyOthers) { app->getCurrentWindow()->navBarTemporaryMode(text, emptyOthers); },
[app]() { app->getCurrentWindow()->navBarRestoreFromTemporaryMode(); },
[app]() { app->getCurrentWindow()->selectSpecialCharacter(); },
- [this]() { this->ContactDataChanged(); }));
+ [&](gui::Text *text) { openTextOptions(text); }));
- internalData.push_back(new gui::InputLinesWithLabelIWidget(
+ internalData.push_back(new gui::InputLinesWithLabelWidget(
phonebookInternals::ListItemName::Email,
- [app](const UTF8 &text) { app->getCurrentWindow()->navBarTemporaryMode(text); },
+ [app](const UTF8 &text, bool emptyOthers) { app->getCurrentWindow()->navBarTemporaryMode(text, emptyOthers); },
[app]() { app->getCurrentWindow()->navBarRestoreFromTemporaryMode(); },
[app]() { app->getCurrentWindow()->selectSpecialCharacter(); },
- [this]() { this->ContactDataChanged(); }));
+ [&](gui::Text *text) { openTextOptions(text); }));
internalData.push_back(new gui::InputBoxWithLabelAndIconWidget(
phonebookInternals::ListItemName::AddToFavourites,
@@ 90,20 88,20 @@ void NewContactModel::createData()
internalData.back()->setMargins(
gui::Margins(style::widgets::leftMargin, style::margins::big, 0, style::margins::very_small));
- internalData.push_back(new gui::InputLinesWithLabelIWidget(
+ internalData.push_back(new gui::InputLinesWithLabelWidget(
phonebookInternals::ListItemName::Address,
- [app](const UTF8 &text) { app->getCurrentWindow()->navBarTemporaryMode(text, false); },
+ [app](const UTF8 &text, bool emptyOthers) { app->getCurrentWindow()->navBarTemporaryMode(text, emptyOthers); },
[app]() { app->getCurrentWindow()->navBarRestoreFromTemporaryMode(); },
[app]() { app->getCurrentWindow()->selectSpecialCharacter(); },
- nullptr,
+ [&](gui::Text *text) { openTextOptions(text); },
2));
- internalData.push_back(new gui::InputLinesWithLabelIWidget(
+ internalData.push_back(new gui::InputLinesWithLabelWidget(
phonebookInternals::ListItemName::Note,
- [app](const UTF8 &text) { app->getCurrentWindow()->navBarTemporaryMode(text, false); },
+ [app](const UTF8 &text, bool emptyOthers) { app->getCurrentWindow()->navBarTemporaryMode(text, emptyOthers); },
[app]() { app->getCurrentWindow()->navBarRestoreFromTemporaryMode(); },
[app]() { app->getCurrentWindow()->selectSpecialCharacter(); },
- nullptr,
+ [&](gui::Text *text) { openTextOptions(text); },
2));
for (auto item : internalData) {
@@ 122,6 120,31 @@ void NewContactModel::clearData()
list->rebuildList();
}
+bool NewContactModel::verifyData()
+{
+ for (auto item : internalData) {
+ if (item->onVerifyCallback) {
+ std::string errorMessage;
+ if (!item->onVerifyCallback(errorMessage)) {
+ auto metaData = std::make_unique<gui::DialogMetadataMessage>(
+ gui::DialogMetadata{errorMessage,
+ "error_W_G",
+ utils::translate("app_phonebook_new_contact_invalid_number"),
+ "",
+ [=]() -> bool {
+ application->returnToPreviousWindow();
+ return true;
+ }});
+
+ application->switchWindow(gui::window::name::dialog, std::move(metaData));
+
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
void NewContactModel::saveData(std::shared_ptr<ContactRecord> contactRecord)
{
for (auto item : internalData) {
@@ 140,16 163,20 @@ void NewContactModel::loadData(std::shared_ptr<ContactRecord> contactRecord)
}
}
-void NewContactModel::ContactDataChanged()
+bool NewContactModel::emptyData()
{
for (auto item : internalData) {
if (item->onEmptyCallback) {
if (!item->onEmptyCallback()) {
- application->getCurrentWindow()->setNavBarActive(gui::nav_bar::Side::Center, true); // SAVE button
- return;
+ return false;
}
}
}
- application->getCurrentWindow()->setNavBarActive(gui::nav_bar::Side::Center, false); // SAVE button
- return;
+ return true;
+}
+
+void NewContactModel::openTextOptions(gui::Text *text)
+{
+ std::unique_ptr<gui::SwitchData> data = std::make_unique<PhonebookInputOptionData>(text);
+ application->switchWindow(gui::window::name::input_options, std::move(data));
}
M module-apps/application-phonebook/models/NewContactModel.hpp => module-apps/application-phonebook/models/NewContactModel.hpp +6 -4
@@ 12,22 12,24 @@
class NewContactModel : public app::InternalModel<gui::ContactListItem *>, public gui::ListItemProvider
{
+ private:
app::ApplicationCommon *application = nullptr;
+ void openTextOptions(gui::Text *text);
+
public:
- NewContactModel(app::ApplicationCommon *app);
+ explicit NewContactModel(app::ApplicationCommon *app);
void clearData();
void saveData(std::shared_ptr<ContactRecord> contactRecord);
void loadData(std::shared_ptr<ContactRecord> contactRecord);
void createData();
+ bool verifyData();
+ bool emptyData();
[[nodiscard]] auto requestRecordsCount() -> unsigned int override;
-
[[nodiscard]] auto getMinimalItemSpaceRequired() const -> unsigned int override;
-
auto getItem(gui::Order order) -> gui::ListItem * override;
void requestRecords(const uint32_t offset, const uint32_t limit) override;
- void ContactDataChanged();
};
R module-apps/application-phonebook/widgets/InputLinesWithLabelIWidget.cpp => module-apps/application-phonebook/widgets/InputLinesWithLabelWidget.cpp +76 -23
@@ 1,24 1,24 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-#include "InputLinesWithLabelIWidget.hpp"
-
-#include <Span.hpp>
+#include "InputLinesWithLabelWidget.hpp"
#include "application-phonebook/data/PhonebookStyle.hpp"
#include <ContactRecord.hpp>
+#include <Clipboard.hpp>
#include <i18n/i18n.hpp>
-#include <utility>
namespace gui
{
- InputLinesWithLabelIWidget::InputLinesWithLabelIWidget(phonebookInternals::ListItemName listItemName,
- std::function<void(const UTF8 &)> navBarTemporaryMode,
- std::function<void()> navBarRestoreFromTemporaryMode,
- std::function<void()> selectSpecialCharacter,
- std::function<void()> contentChanged,
- unsigned int lines)
- : listItemName(listItemName), checkTextContent(std::move(contentChanged))
+ InputLinesWithLabelWidget::InputLinesWithLabelWidget(
+ phonebookInternals::ListItemName listItemName,
+ const std::function<void(const UTF8 &text, bool emptyOthers)> &navBarTemporaryMode,
+ const std::function<void()> &navBarRestoreFromTemporaryMode,
+ const std::function<void()> &selectSpecialCharacter,
+ const std::function<void(Text *text)> &inputOptions,
+ unsigned int lines)
+ : listItemName(listItemName), navBarTemporaryMode(navBarTemporaryMode),
+ navBarRestoreFromTemporaryMode(navBarRestoreFromTemporaryMode), inputOptions(inputOptions)
{
setMinimumSize(phonebookStyle::inputLinesWithLabelWidget::w,
phonebookStyle::inputLinesWithLabelWidget::title_label_h +
@@ 52,8 52,8 @@ namespace gui
inputText->setFont(style::window::font::medium);
inputText->setInputMode(new InputMode(
{InputMode::ABC, InputMode::abc, InputMode::digit},
- [=](const UTF8 &text) { navBarTemporaryMode(text); },
- [=]() { navBarRestoreFromTemporaryMode(); },
+ [=](const UTF8 &text) { this->navBarTemporaryMode(text, true); },
+ [=]() { this->navBarRestoreFromTemporaryMode(); },
[=]() { selectSpecialCharacter(); }));
inputText->setPenFocusWidth(style::window::default_border_focus_w);
inputText->setPenWidth(style::window::default_border_no_focus_w);
@@ 68,20 68,36 @@ namespace gui
inputText->setCursorStartPosition(CursorStartPosition::DocumentEnd);
inputText->setUnderlineThickness(style::window::default_border_focus_w);
inputText->setFont(style::window::font::mediumbold);
+
+ if (!inputText->isEmpty() || Clipboard::getInstance().gotData()) {
+ this->navBarTemporaryMode(utils::translate(style::strings::common::options), false);
+ }
}
else {
inputText->setCursorStartPosition(CursorStartPosition::DocumentBegin);
inputText->setUnderlineThickness(style::window::default_border_rect_no_focus);
inputText->setFont(style::window::font::medium);
+
+ this->navBarRestoreFromTemporaryMode();
}
return true;
};
inputCallback = [&](Item &item, const InputEvent &event) {
auto result = inputText->onInput(event);
- if (checkTextContent != nullptr) {
- checkTextContent();
+
+ if (!event.isShortRelease(gui::KeyCode::KEY_AST) &&
+ (!inputText->isEmpty() || Clipboard::getInstance().gotData())) {
+ this->navBarTemporaryMode(utils::translate(style::strings::common::options), false);
+ }
+
+ if (event.isShortRelease(gui::KeyCode::KEY_LF) &&
+ (!inputText->isEmpty() || Clipboard::getInstance().gotData())) {
+ if (this->inputOptions) {
+ this->inputOptions(inputText);
+ }
}
+
return result;
};
@@ 93,7 109,7 @@ namespace gui
setEdges(RectangleEdge::None);
}
- void InputLinesWithLabelIWidget::applyItemNameSpecificSettings()
+ void InputLinesWithLabelWidget::applyItemNameSpecificSettings()
{
switch (listItemName) {
case phonebookInternals::ListItemName::FirstName:
@@ 129,19 145,23 @@ namespace gui
break;
}
}
- void InputLinesWithLabelIWidget::firstNameHandler()
+ void InputLinesWithLabelWidget::firstNameHandler()
{
titleLabel->setText(utils::translate("app_phonebook_new_contact_first_name"));
inputText->setTextType(TextType::SingleLine);
+ inputText->setTextLimitType(TextLimitType::MaxSignsCount,
+ phonebookStyle::inputLinesWithLabelWidget::minimum_signs_limit);
onSaveCallback = [&](std::shared_ptr<ContactRecord> contact) { contact->primaryName = inputText->getText(); };
onLoadCallback = [&](std::shared_ptr<ContactRecord> contact) { inputText->setText(contact->primaryName); };
onEmptyCallback = [&]() { return inputText->isEmpty(); };
}
- void InputLinesWithLabelIWidget::secondNameHandler()
+ void InputLinesWithLabelWidget::secondNameHandler()
{
titleLabel->setText(utils::translate("app_phonebook_new_contact_last_name"));
inputText->setTextType(TextType::SingleLine);
+ inputText->setTextLimitType(TextLimitType::MaxSignsCount,
+ phonebookStyle::inputLinesWithLabelWidget::minimum_signs_limit);
onSaveCallback = [&](std::shared_ptr<ContactRecord> contact) {
contact->alternativeName = inputText->getText();
@@ 149,11 169,13 @@ namespace gui
onLoadCallback = [&](std::shared_ptr<ContactRecord> contact) { inputText->setText(contact->alternativeName); };
onEmptyCallback = [&]() { return inputText->isEmpty(); };
}
- void InputLinesWithLabelIWidget::numberHandler()
+ void InputLinesWithLabelWidget::numberHandler()
{
titleLabel->setText(utils::translate("app_phonebook_new_contact_number"));
inputText->setTextType(TextType::SingleLine);
inputText->setInputMode(new InputMode({InputMode::phone}));
+ inputText->setTextLimitType(TextLimitType::MaxSignsCount,
+ phonebookStyle::inputLinesWithLabelWidget::medium_signs_limit);
onSaveCallback = [&](std::shared_ptr<ContactRecord> contact) {
if (inputText->getText().length() > 0) {
@@ 166,13 188,26 @@ namespace gui
inputText->setText(contact->numbers[0].number.getEntered());
}
};
+
+ onVerifyCallback = [&](std::string &errorMessage) {
+ if (utils::is_phone_number(inputText->getText())) {
+ return true;
+ }
+ else {
+ errorMessage = inputText->getText();
+ return false;
+ }
+ };
+
onEmptyCallback = [&]() { return inputText->isEmpty(); };
}
- void InputLinesWithLabelIWidget::secondNumberHandler()
+ void InputLinesWithLabelWidget::secondNumberHandler()
{
titleLabel->setText(utils::translate("app_phonebook_new_contact_second_number"));
inputText->setTextType(TextType::SingleLine);
inputText->setInputMode(new InputMode({InputMode::phone}));
+ inputText->setTextLimitType(TextLimitType::MaxSignsCount,
+ phonebookStyle::inputLinesWithLabelWidget::medium_signs_limit);
onSaveCallback = [&](std::shared_ptr<ContactRecord> contact) {
if (inputText->getText().length() > 0) {
@@ 180,34 215,52 @@ namespace gui
ContactRecord::Number(utils::PhoneNumber(inputText->getText()).getView()));
}
};
+
onLoadCallback = [&](std::shared_ptr<ContactRecord> contact) {
if (contact->numbers.size() > 1) {
inputText->setText(contact->numbers[1].number.getEntered());
}
};
+
+ onVerifyCallback = [&](std::string &errorMessage) {
+ if (utils::is_phone_number(inputText->getText())) {
+ return true;
+ }
+ else {
+ errorMessage = inputText->getText();
+ return false;
+ }
+ };
+
onEmptyCallback = [&]() { return inputText->isEmpty(); };
}
- void InputLinesWithLabelIWidget::emailHandler()
+ void InputLinesWithLabelWidget::emailHandler()
{
titleLabel->setText(utils::translate("app_phonebook_new_contact_email"));
inputText->setTextType(TextType::SingleLine);
+ inputText->setTextLimitType(TextLimitType::MaxSignsCount,
+ phonebookStyle::inputLinesWithLabelWidget::max_signs_limit);
onSaveCallback = [&](std::shared_ptr<ContactRecord> contact) { contact->mail = inputText->getText(); };
onLoadCallback = [&](std::shared_ptr<ContactRecord> contact) { inputText->setText(contact->mail); };
onEmptyCallback = [&]() { return inputText->isEmpty(); };
}
- void InputLinesWithLabelIWidget::addressHandler()
+ void InputLinesWithLabelWidget::addressHandler()
{
titleLabel->setText(utils::translate("app_phonebook_new_contact_address"));
inputText->setTextType(TextType::SingleLine);
+ inputText->setTextLimitType(TextLimitType::MaxSignsCount,
+ phonebookStyle::inputLinesWithLabelWidget::max_signs_limit);
onSaveCallback = [&](std::shared_ptr<ContactRecord> contact) { contact->address = inputText->getText(); };
onLoadCallback = [&](std::shared_ptr<ContactRecord> contact) { inputText->setText(contact->address); };
}
- void InputLinesWithLabelIWidget::noteHandler()
+ void InputLinesWithLabelWidget::noteHandler()
{
titleLabel->setText(utils::translate("app_phonebook_new_contact_note"));
inputText->setTextType(TextType::SingleLine);
+ inputText->setTextLimitType(TextLimitType::MaxSignsCount,
+ phonebookStyle::inputLinesWithLabelWidget::max_signs_limit);
onSaveCallback = [&](std::shared_ptr<ContactRecord> contact) { contact->note = inputText->getText(); };
onLoadCallback = [&](std::shared_ptr<ContactRecord> contact) { inputText->setText(contact->note); };
R module-apps/application-phonebook/widgets/InputLinesWithLabelIWidget.hpp => module-apps/application-phonebook/widgets/InputLinesWithLabelWidget.hpp +14 -12
@@ 13,27 13,29 @@
namespace gui
{
- class InputLinesWithLabelIWidget : public ContactListItem
+ class InputLinesWithLabelWidget : public ContactListItem
{
- phonebookInternals::ListItemName listItemName;
-
public:
- InputLinesWithLabelIWidget(phonebookInternals::ListItemName listItemName,
- std::function<void(const UTF8 &text)> navBarTemporaryMode = nullptr,
- std::function<void()> navBarRestoreFromTemporaryMode = nullptr,
- std::function<void()> selectSpecialCharacter = nullptr,
- std::function<void()> contentChanged = nullptr,
- unsigned int lines = 1);
-
- ~InputLinesWithLabelIWidget() override = default;
+ 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()> &selectSpecialCharacter = nullptr,
+ const std::function<void(Text *text)> &inputOptions = nullptr,
+ unsigned int lines = 1);
+
VBox *vBox = nullptr;
Label *titleLabel = nullptr;
TextFixedSize *inputText = nullptr;
private:
- std::function<void()> checkTextContent = nullptr;
+ phonebookInternals::ListItemName listItemName;
void applyItemNameSpecificSettings();
+ std::function<void(const UTF8 &text, bool emptyOthers)> navBarTemporaryMode = nullptr;
+ std::function<void()> navBarRestoreFromTemporaryMode = nullptr;
+ std::function<void(Text *text)> inputOptions = nullptr;
+
void firstNameHandler();
void secondNameHandler();
void numberHandler();
A module-apps/application-phonebook/windows/PhonebookInputOptions.cpp => module-apps/application-phonebook/windows/PhonebookInputOptions.cpp +46 -0
@@ 0,0 1,46 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#include "PhonebookInputOptions.hpp"
+#include "application-phonebook/data/PhonebookItemData.hpp"
+
+#include <Clipboard.hpp>
+#include <ApplicationCommon.hpp>
+
+namespace gui
+{
+ PhonebookInputOptions::PhonebookInputOptions(app::ApplicationCommon *app, std::string windowName)
+ : OptionWindow(app, windowName)
+ {}
+
+ void PhonebookInputOptions::onBeforeShow(ShowMode mode, SwitchData *data)
+ {
+ if (auto message = dynamic_cast<PhonebookInputOptionData *>(data)) {
+ addOptions(inputOptionsList(message->getInputText()));
+ optionsList->rebuildList();
+ }
+ }
+
+ auto PhonebookInputOptions::inputOptionsList(gui::Text *text) -> std::list<gui::Option>
+ {
+ std::list<gui::Option> options;
+
+ if (!text->isEmpty()) {
+ options.emplace_back(utils::translate("common_text_copy"), [=](gui::Item &item) {
+ Clipboard::getInstance().copy(text->getText());
+ application->returnToPreviousWindow();
+ return true;
+ });
+ }
+
+ if (Clipboard::getInstance().gotData()) {
+ options.emplace_back(utils::translate("common_text_paste"), [=](gui::Item &item) {
+ text->addText(Clipboard::getInstance().paste(), AdditionType::perBlock);
+ application->returnToPreviousWindow();
+ return true;
+ });
+ }
+
+ return options;
+ }
+} // namespace gui
A module-apps/application-phonebook/windows/PhonebookInputOptions.hpp => module-apps/application-phonebook/windows/PhonebookInputOptions.hpp +19 -0
@@ 0,0 1,19 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#pragma once
+
+#include "OptionWindow.hpp"
+
+namespace gui
+{
+ class PhonebookInputOptions : public OptionWindow
+ {
+ public:
+ PhonebookInputOptions(app::ApplicationCommon *app, std::string windowName);
+ void onBeforeShow(ShowMode mode, SwitchData *data) override;
+
+ private:
+ auto inputOptionsList(gui::Text *text) -> std::list<gui::Option>;
+ };
+} // namespace gui
M module-apps/application-phonebook/windows/PhonebookNewContact.cpp => module-apps/application-phonebook/windows/PhonebookNewContact.cpp +7 -14
@@ 53,6 53,7 @@ namespace gui
{
if (mode != ShowMode::GUI_SHOW_RETURN) {
newContactModel->clearData();
+ newContactModel->loadData(contact);
}
if (mode == ShowMode::GUI_SHOW_INIT) {
@@ 71,7 72,7 @@ namespace gui
break;
}
- newContactModel->loadData(contact);
+ !newContactModel->emptyData() ? setSaveButtonVisible(true) : setSaveButtonVisible(false);
}
auto PhonebookNewContact::handleSwitchData(SwitchData *data) -> bool
@@ 89,20 90,17 @@ namespace gui
if (contact == nullptr) {
contactAction = ContactAction::Add;
contact = std::make_shared<ContactRecord>();
- setSaveButtonVisible(false);
return true;
}
if (contact->ID == DB_ID_NONE) {
contactAction = ContactAction::Add;
- setSaveButtonVisible(false);
}
else if (contact->isTemporary()) {
contactAction = ContactAction::EditTemporary;
}
else {
contactAction = ContactAction::Edit;
- setSaveButtonVisible(true);
}
return true;
@@ 115,15 113,12 @@ namespace gui
auto PhonebookNewContact::onInput(const InputEvent &inputEvent) -> bool
{
- if (AppWindow::onInput(inputEvent)) {
- return true;
- }
+ auto ret = AppWindow::onInput(inputEvent);
- if (!inputEvent.isShortRelease()) {
- return false;
- }
+ !newContactModel->emptyData() ? setSaveButtonVisible(true) : setSaveButtonVisible(false);
- if (inputEvent.is(gui::KeyCode::KEY_ENTER)) {
+ if (inputEvent.isShortRelease(gui::KeyCode::KEY_ENTER) && !newContactModel->emptyData() &&
+ newContactModel->verifyData()) {
auto tmpId = contact->ID;
contact = std::make_shared<ContactRecord>();
contact->ID = tmpId;
@@ 134,9 129,7 @@ namespace gui
return true;
}
- application->refreshWindow(RefreshModes::GUI_REFRESH_FAST);
-
- return false;
+ return ret;
}
auto PhonebookNewContact::verifyAndSave() -> bool
M module-gui/gui/widgets/ListItem.hpp => module-gui/gui/widgets/ListItem.hpp +5 -4
@@ 21,9 21,10 @@ namespace gui
template <class T> class ListItemWithCallbacks : public ListItem
{
public:
- std::function<bool()> onEmptyCallback = nullptr;
- std::function<bool()> onContentChangedCallback = nullptr;
- std::function<void(std::shared_ptr<T> record)> onSaveCallback = nullptr;
- std::function<void(std::shared_ptr<T> record)> onLoadCallback = nullptr;
+ std::function<bool()> onEmptyCallback = nullptr;
+ std::function<bool()> onContentChangedCallback = nullptr;
+ std::function<bool(std::string &errorMessage)> onVerifyCallback = nullptr;
+ std::function<void(std::shared_ptr<T> record)> onSaveCallback = nullptr;
+ std::function<void(std::shared_ptr<T> record)> onLoadCallback = nullptr;
};
} /* namespace gui */
M => +1 -1
@@ 34,7 34,7 @@ namespace gui::header
Item *Header::createTitle(const UTF8 &text)
{
title = new gui::Label(nullptr, 0, 0, 0, 0);
title->setMaximumSize(getWidth(), getHeight());
title->setMaximumSize(getWidth() - 2 * style::header::title::margins, getHeight());
title->setFont(style::header::font::title);
title->setAlignment(gui::Alignment(gui::Alignment::Horizontal::Center, gui::Alignment::Vertical::Top));
title->setPadding(gui::Padding(0, style::header::title::top_padding, 0, 0));
M => +1 -0
@@ 10,6 10,7 @@ namespace style::header
namespace title
{
inline constexpr auto top_padding = 6u;
inline constexpr auto margins = 30u;
}; // namespace title
namespace navigation_indicator
M module-gui/gui/widgets/text/Text.cpp => module-gui/gui/widgets/text/Text.cpp +11 -2
@@ 121,12 121,21 @@ namespace gui
textChangedCallback = std::move(callback);
}
- void Text::addText(const UTF8 &text)
+ void Text::addText(const UTF8 &text, AdditionType additionType)
{
if (text.length() == 0) {
return;
}
- *cursor << text;
+
+ if (additionType == AdditionType::perChar) {
+ *cursor << text;
+ }
+ else if (additionType == AdditionType::perBlock) {
+ for (const auto &block : textToTextBlocks(text, format)) {
+ *cursor << block;
+ }
+ }
+
onTextChanged();
drawLines();
}
M module-gui/gui/widgets/text/Text.hpp => module-gui/gui/widgets/text/Text.hpp +1 -1
@@ 138,7 138,7 @@ namespace gui
void setTextChangedCallback(TextChangedCallback &&callback);
- void addText(const UTF8 &text);
+ void addText(const UTF8 &text, AdditionType additionType = AdditionType::perChar);
void addText(TextBlock text);
/// @defgroup richtext can be virtualized by parametrized RichTextParser virtual api ( as second param )
/// @{
M module-gui/gui/widgets/text/TextConstants.hpp => module-gui/gui/widgets/text/TextConstants.hpp +6 -0
@@ 68,4 68,10 @@ namespace gui
CantAdd
};
+ enum class AdditionType
+ {
+ perChar,
+ perBlock
+ };
+
} // namespace gui
M module-utils/utility/Utils.hpp => module-utils/utility/Utils.hpp +5 -0
@@ 45,6 45,11 @@ namespace utils
return !s.empty() && std::find_if(s.begin(), s.end(), [](char c) { return !std::isdigit(c); }) == s.end();
}
+ static inline bool is_phone_number(const std::string &s)
+ {
+ return s.find_first_not_of(" +#0123456789") == std::string::npos;
+ }
+
static inline std::string ltrim(const std::string &s)
{
size_t start = s.find_first_not_of(WHITESPACE);