M changelog.md => changelog.md +1 -0
@@ 6,6 6,7 @@
* Add hardware in the loop tests.
* Add empty APN settings window.
+* Add New/Edit APN window
### Changed
M image/assets/lang/English.json => image/assets/lang/English.json +8 -0
@@ 363,6 363,14 @@
"app_settings_security_wrong_passcode": "Wrong passcode!",
"app_settings_security_passcode_changed_successfully": "Passcode changed successfully!",
"app_settings_security_passcode_disabled": "Passcode disabled!",
+ "app_settings_new_edit_apn": "New/Edit APN",
+ "app_settings_apn_name": "Name",
+ "app_settings_apn_APN": "APN",
+ "app_settings_apn_username": "UserName",
+ "app_settings_apn_password": "Password",
+ "app_settings_apn_authtype": "Authentication type",
+ "app_settings_apn_apntype": "APN Type",
+ "app_settings_apn_apnprotocol" : "APN Protocol",
"app_phonebook_title_main": "Contacts",
"app_phonebook_search_win_contacts": "Contacts",
"common_search_uc": "Search",
M module-apps/application-settings-new/ApplicationSettings.cpp => module-apps/application-settings-new/ApplicationSettings.cpp +13 -0
@@ 28,6 28,7 @@
#include "windows/QuotesOptionsWindow.hpp"
#include "windows/ChangePasscodeWindow.hpp"
#include "windows/SystemMainWindow.hpp"
+#include "windows/NewApnWindow.hpp"
#include "Dialog.hpp"
@@ 233,9 234,21 @@ namespace app
windowsFactory.attach(gui::window::name::security, [](Application *app, const std::string &name) {
return std::make_unique<gui::SecurityMainWindow>(app);
});
+
windowsFactory.attach(gui::window::name::system, [](Application *app, const std::string &name) {
return std::make_unique<gui::SystemMainWindow>(app);
});
+
+ windowsFactory.attach(gui::window::name::change_passcode, [](Application *app, const std::string &name) {
+ return std::make_unique<gui::ChangePasscodeWindow>(app);
+ });
+ windowsFactory.attach(gui::window::name::dialog_confirm, [](Application *app, const std::string &name) {
+ return std::make_unique<gui::DialogConfirm>(app, gui::window::name::dialog_confirm);
+ });
+
+ windowsFactory.attach(gui::window::name::new_apn, [](Application *app, const std::string &name) {
+ return std::make_unique<gui::NewApnWindow>(app);
+ });
}
void ApplicationSettingsNew::destroyUserInterface()
M module-apps/application-settings-new/ApplicationSettings.hpp => module-apps/application-settings-new/ApplicationSettings.hpp +2 -0
@@ 55,6 55,8 @@ namespace gui::window::name
inline constexpr auto about_your_pure = "AboutYourPure";
inline constexpr auto certification = "Certification";
+ inline constexpr auto new_apn = "NewApn";
+
} // namespace gui::window::name
namespace app
M module-apps/application-settings-new/CMakeLists.txt => module-apps/application-settings-new/CMakeLists.txt +7 -0
@@ 18,6 18,7 @@ target_sources( ${PROJECT_NAME}
widgets/timeWidget.cpp
widgets/ChangePasscodeLockHandler.cpp
widgets/QuoteWidget.cpp
+ widgets/ApnInputWidget.cpp
windows/SettingsMainWindow.cpp
windows/AddDeviceWindow.cpp
windows/AllDevicesWindow.cpp
@@ 42,12 43,17 @@ target_sources( ${PROJECT_NAME}
windows/QuotesAddWindow.cpp
windows/SecurityMainWindow.cpp
windows/ChangePasscodeWindow.cpp
+ windows/NewApnWindow.cpp
+ models/NewApnModel.cpp
widgets/SpinBox.cpp
widgets/SpinBoxOptionSetting.cpp
windows/SystemMainWindow.cpp
PUBLIC
ApplicationSettings.hpp
+ widgets/ChangePasscodeLockHandler.hpp
+ widgets/ApnInputWidget.hpp
+ windows/NewApnWindow.hpp
windows/SettingsMainWindow.hpp
windows/BaseSettingsWindow.hpp
windows/FontSizeWindow.hpp
@@ 62,6 68,7 @@ target_sources( ${PROJECT_NAME}
windows/AutolockWindow.hpp
windows/WallpaperWindow.hpp
windows/SystemMainWindow.hpp
+ windows/ChangePasscodeWindow.hpp
)
add_dependencies(${PROJECT_NAME} version)
A module-apps/application-settings-new/data/SettingsInternals.hpp => module-apps/application-settings-new/data/SettingsInternals.hpp +30 -0
@@ 0,0 1,30 @@
+// 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 <cstdint>
+
+namespace settingsInternals
+{
+ enum class ListItemName
+ {
+ Name,
+ APN,
+ Proxy,
+ Port,
+ Username,
+ Password,
+
+ Server,
+ MMSC,
+ MmsProxy,
+ MmsPort,
+ MCC,
+ MNC,
+ AuthType,
+ ApnType,
+ ApnProtocol
+ };
+
+} // namespace settingsInternals
A module-apps/application-settings-new/data/SettingsItemData.hpp => module-apps/application-settings-new/data/SettingsItemData.hpp +23 -0
@@ 0,0 1,23 @@
+// 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 <service-cellular/service-cellular/PacketDataTypes.hpp>
+#include <ListItem.hpp>
+#include <SwitchData.hpp>
+
+class ApnItemData : public gui::SwitchData
+{
+ public:
+ ApnItemData(std::shared_ptr<packet_data::APN::Config> Apn) : apn(std::move(Apn)){};
+ ApnItemData() : apn(nullptr){};
+
+ auto getApn() -> std::shared_ptr<packet_data::APN::Config>
+ {
+ return apn;
+ }
+
+ private:
+ std::shared_ptr<packet_data::APN::Config> apn;
+};
A module-apps/application-settings-new/models/NewApnModel.cpp => module-apps/application-settings-new/models/NewApnModel.cpp +140 -0
@@ 0,0 1,140 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#include "NewApnModel.hpp"
+
+#include "AppWindow.hpp"
+#include "application-settings-new/widgets/ApnInputWidget.hpp"
+#include <service-cellular/service-cellular/CellularServiceAPI.hpp>
+
+#include <ListView.hpp>
+#include <time/ScopedTime.hpp>
+#include <BottomBar.hpp>
+
+NewApnModel::NewApnModel(app::Application *app) : application(app)
+{}
+
+auto NewApnModel::requestRecordsCount() -> unsigned int
+{
+ return internalData.size();
+}
+
+auto NewApnModel::getMinimalItemHeight() const -> unsigned int
+{
+ return style::settings::widget::apnInputWidget::h;
+}
+
+void NewApnModel::requestRecords(const uint32_t offset, const uint32_t limit)
+{
+ setupModel(offset, limit);
+ list->onProviderDataUpdate();
+}
+
+auto NewApnModel::getItem(gui::Order order) -> gui::ListItem *
+{
+ return getRecord(order);
+}
+
+void NewApnModel::createData()
+{
+ auto app = application;
+
+ internalData.emplace_back(new gui::ApnInputWidget(
+ settingsInternals::ListItemName::Name,
+ [app](const UTF8 &text) { app->getCurrentWindow()->bottomBarTemporaryMode(text); },
+ [app]() { app->getCurrentWindow()->bottomBarRestoreFromTemporaryMode(); },
+ [app]() { app->getCurrentWindow()->selectSpecialCharacter(); },
+ [this]() { this->apnDataChanged(); }));
+
+ internalData.emplace_back(new gui::ApnInputWidget(
+ settingsInternals::ListItemName::APN,
+ [app](const UTF8 &text) { app->getCurrentWindow()->bottomBarTemporaryMode(text); },
+ [app]() { app->getCurrentWindow()->bottomBarRestoreFromTemporaryMode(); },
+ [app]() { app->getCurrentWindow()->selectSpecialCharacter(); },
+ [this]() { this->apnDataChanged(); }));
+
+ internalData.emplace_back(new gui::ApnInputWidget(
+ settingsInternals::ListItemName::Username,
+ [app](const UTF8 &text) { app->getCurrentWindow()->bottomBarTemporaryMode(text); },
+ [app]() { app->getCurrentWindow()->bottomBarRestoreFromTemporaryMode(); },
+ [app]() { app->getCurrentWindow()->selectSpecialCharacter(); },
+ [this]() { this->apnDataChanged(); }));
+
+ internalData.emplace_back(new gui::ApnInputWidget(
+ settingsInternals::ListItemName::Password,
+ [app](const UTF8 &text) { app->getCurrentWindow()->bottomBarTemporaryMode(text); },
+ [app]() { app->getCurrentWindow()->bottomBarRestoreFromTemporaryMode(); },
+ [app]() { app->getCurrentWindow()->selectSpecialCharacter(); },
+ [this]() { this->apnDataChanged(); }));
+
+ internalData.emplace_back(new gui::ApnInputWidget(
+ settingsInternals::ListItemName::AuthType,
+ [app](const UTF8 &text) { app->getCurrentWindow()->bottomBarTemporaryMode(text); },
+ [app]() { app->getCurrentWindow()->bottomBarRestoreFromTemporaryMode(); },
+ [app]() { app->getCurrentWindow()->selectSpecialCharacter(); },
+ [this]() { this->apnDataChanged(); }));
+
+ internalData.emplace_back(new gui::ApnInputWidget(
+ settingsInternals::ListItemName::ApnType,
+ [app](const UTF8 &text) { app->getCurrentWindow()->bottomBarTemporaryMode(text); },
+ [app]() { app->getCurrentWindow()->bottomBarRestoreFromTemporaryMode(); },
+ [app]() { app->getCurrentWindow()->selectSpecialCharacter(); },
+ [this]() { this->apnDataChanged(); }));
+
+ internalData.emplace_back(new gui::ApnInputWidget(
+ settingsInternals::ListItemName::ApnProtocol,
+ [app](const UTF8 &text) { app->getCurrentWindow()->bottomBarTemporaryMode(text); },
+ [app]() { app->getCurrentWindow()->bottomBarRestoreFromTemporaryMode(); },
+ [app]() { app->getCurrentWindow()->selectSpecialCharacter(); },
+ [this]() { this->apnDataChanged(); }));
+
+ for (auto item : internalData) {
+ item->deleteByList = false;
+ }
+}
+
+void NewApnModel::clearData()
+{
+ list->clear();
+
+ eraseInternalData();
+
+ createData();
+
+ list->rebuildList();
+}
+
+void NewApnModel::saveData(std::shared_ptr<packet_data::APN::Config> apnRecord)
+{
+ for (auto item : internalData) {
+ if (item->onSaveCallback) {
+ item->onSaveCallback(apnRecord);
+ }
+ }
+}
+
+void NewApnModel::loadData(std::shared_ptr<packet_data::APN::Config> apnRecord)
+{
+ for (auto item : internalData) {
+ if (item->onLoadCallback) {
+ item->onLoadCallback(apnRecord);
+ }
+ }
+}
+
+void NewApnModel::apnDataChanged()
+{
+ for (auto item : internalData) {
+ if (item->onEmptyCallback && !item->onEmptyCallback()) {
+ application->getCurrentWindow()->setBottomBarActive(gui::BottomBar::Side::CENTER, true); // SAVE button
+ return;
+ }
+ }
+ application->getCurrentWindow()->setBottomBarActive(gui::BottomBar::Side::CENTER, false); // SAVE button
+ return;
+}
+
+void NewApnModel::apnSendRecord(packet_data::APN::Config apnRecord)
+{
+ CellularServiceAPI::SetAPN(application, apnRecord);
+}
A module-apps/application-settings-new/models/NewApnModel.hpp => module-apps/application-settings-new/models/NewApnModel.hpp +36 -0
@@ 0,0 1,36 @@
+// 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 "application-settings-new/data/SettingsItemData.hpp"
+#include "application-settings-new/widgets/ApnListItem.hpp"
+#include "application-settings-new/widgets/SettingsStyle.hpp"
+#include "InternalModel.hpp"
+#include "Application.hpp"
+
+#include <ListItemProvider.hpp>
+
+class NewApnModel : public app::InternalModel<gui::ApnListItem *>, public gui::ListItemProvider
+{
+ app::Application *application = nullptr;
+
+ public:
+ NewApnModel(app::Application *app);
+
+ void clearData();
+ void saveData(std::shared_ptr<packet_data::APN::Config> apnRecord);
+ void loadData(std::shared_ptr<packet_data::APN::Config> apnRecord);
+
+ void createData();
+
+ [[nodiscard]] auto requestRecordsCount() -> unsigned int override;
+
+ [[nodiscard]] auto getMinimalItemHeight() const -> unsigned int override;
+
+ auto getItem(gui::Order order) -> gui::ListItem * override;
+
+ void requestRecords(const uint32_t offset, const uint32_t limit) override;
+ void apnDataChanged();
+ void apnSendRecord(packet_data::APN::Config apnRecord);
+};
A module-apps/application-settings-new/widgets/ApnInputWidget.cpp => module-apps/application-settings-new/widgets/ApnInputWidget.cpp +221 -0
@@ 0,0 1,221 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#include "ApnInputWidget.hpp"
+#include <Span.hpp>
+#include "application-settings-new/widgets/SettingsStyle.hpp"
+#include <i18n/i18n.hpp>
+#include <utility>
+
+namespace gui
+{
+ ApnInputWidget::ApnInputWidget(settingsInternals::ListItemName listItemName,
+ std::function<void(const UTF8 &)> bottomBarTemporaryMode,
+ std::function<void()> bottomBarRestoreFromTemporaryMode,
+ std::function<void()> selectSpecialCharacter,
+ std::function<void()> contentChanged,
+ unsigned int lines)
+ : listItemName(listItemName), checkTextContent(std::move(contentChanged))
+ {
+
+ setMinimumSize(style::settings::widget::apnInputWidget::w,
+ style::settings::widget::apnInputWidget::title_label_h +
+ style::settings::widget::apnInputWidget::span_size +
+ style::settings::widget::apnInputWidget::input_text_h * lines);
+
+ setMargins(gui::Margins(0, style::margins::huge, 0, 0));
+
+ vBox = new VBox(this, 0, 0, 0, 0);
+ vBox->setEdges(RectangleEdge::None);
+
+ titleLabel = new Label(vBox);
+ titleLabel->setMinimumSize(style::settings::widget::apnInputWidget::w,
+ style::settings::widget::apnInputWidget::title_label_h);
+ titleLabel->setEdges(RectangleEdge::None);
+ titleLabel->setAlignment(Alignment(gui::Alignment::Horizontal::Left, gui::Alignment::Vertical::Top));
+ titleLabel->setFont(style::window::font::verysmall);
+ titleLabel->activeItem = false;
+
+ inputText = new TextFixedSize(vBox, 0, 0, 0, 0);
+ inputText->setMinimumSize(style::settings::widget::apnInputWidget::w,
+ style::settings::widget::apnInputWidget::input_text_h * lines);
+ inputText->setMargins(Margins(0, style::settings::widget::apnInputWidget::span_size, 0, 0));
+ inputText->setUnderlinePadding(style::settings::widget::apnInputWidget::underline_padding);
+
+ inputText->setEdges(RectangleEdge::None);
+ inputText->setAlignment(Alignment(gui::Alignment::Horizontal::Left, gui::Alignment::Vertical::Top));
+ inputText->setFont(style::window::font::medium);
+ inputText->setInputMode(new InputMode(
+ {InputMode::ABC, InputMode::abc, InputMode::digit},
+ [=](const UTF8 &text) { bottomBarTemporaryMode(text); },
+ [=]() { bottomBarRestoreFromTemporaryMode(); },
+ [=]() { selectSpecialCharacter(); }));
+ inputText->setPenFocusWidth(style::window::default_border_focus_w);
+ inputText->setPenWidth(style::window::default_border_no_focus_w);
+ inputText->setEditMode(EditMode::Edit);
+
+ applyItemNameSpecificSettings();
+
+ focusChangedCallback = [&](Item &item) {
+ setFocusItem(focus ? vBox : nullptr);
+
+ auto tempText = inputText->getText();
+
+ if (focus) {
+ inputText->setFont(style::window::font::mediumbold);
+ inputText->setText(tempText);
+ }
+ else {
+ inputText->setFont(style::window::font::medium);
+ inputText->setText(tempText);
+ }
+ return true;
+ };
+
+ inputCallback = [&](Item &item, const InputEvent &event) {
+ auto result = inputText->onInput(event);
+ if (checkTextContent != nullptr) {
+ checkTextContent();
+ }
+ return result;
+ };
+ setEdges(RectangleEdge::None);
+ }
+
+ auto ApnInputWidget::onDimensionChanged(const BoundingBox &oldDim, const BoundingBox &newDim) -> bool
+ {
+ vBox->setPosition(0, 0);
+ vBox->setSize(newDim.w, newDim.h);
+
+ return true;
+ }
+
+ void ApnInputWidget::applyItemNameSpecificSettings()
+ {
+ switch (listItemName) {
+
+ case settingsInternals::ListItemName::Name:
+ nameHandler();
+ break;
+
+ case settingsInternals::ListItemName::APN:
+ apnHandler();
+ break;
+
+ case settingsInternals::ListItemName::Username:
+ usernameHandler();
+ break;
+
+ case settingsInternals::ListItemName::Password:
+ passwordNumberHandler();
+ break;
+
+ case settingsInternals::ListItemName::AuthType:
+ authtypeHandler();
+ break;
+
+ case settingsInternals::ListItemName::ApnType:
+ apntypeHandler();
+ break;
+
+ case settingsInternals::ListItemName::ApnProtocol:
+ protocolHandler();
+ break;
+
+ default:
+ LOG_ERROR("Incorrect List Item Name!");
+ break;
+ }
+ }
+
+ void ApnInputWidget::nameHandler()
+ {
+ titleLabel->setText(utils::localize.get("app_settings_apn_name"));
+ inputText->setTextType(TextType::SingleLine);
+ onSaveCallback = [&](std::shared_ptr<packet_data::APN::Config> apnRecord) {
+ apnRecord->apn = inputText->getText();
+ };
+ onLoadCallback = [&](std::shared_ptr<packet_data::APN::Config> apnRecord) {
+ inputText->setText(apnRecord->apn);
+ };
+ onEmptyCallback = [&]() { return inputText->isEmpty(); };
+ }
+
+ void ApnInputWidget::apnHandler()
+ {
+ titleLabel->setText(utils::localize.get("app_settings_apn_APN"));
+ inputText->setTextType(TextType::SingleLine);
+ onSaveCallback = [&](std::shared_ptr<packet_data::APN::Config> apnRecord) {
+ apnRecord->ip = inputText->getText();
+ };
+ onLoadCallback = [&](std::shared_ptr<packet_data::APN::Config> apnRecord) {
+ inputText->setText(apnRecord->ip);
+ };
+ onEmptyCallback = [&]() { return inputText->isEmpty(); };
+ }
+
+ void ApnInputWidget::usernameHandler()
+ {
+ titleLabel->setText(utils::localize.get("app_settings_apn_username"));
+ inputText->setTextType(TextType::SingleLine);
+ onSaveCallback = [&](std::shared_ptr<packet_data::APN::Config> apnRecord) {
+ apnRecord->username = inputText->getText();
+ };
+ onLoadCallback = [&](std::shared_ptr<packet_data::APN::Config> apnRecord) {
+ inputText->setText(apnRecord->username);
+ };
+ onEmptyCallback = [&]() { return inputText->isEmpty(); };
+ }
+
+ void ApnInputWidget::passwordNumberHandler()
+ {
+ titleLabel->setText(utils::localize.get("app_settings_apn_password"));
+ inputText->setTextType(TextType::SingleLine);
+ onSaveCallback = [&](std::shared_ptr<packet_data::APN::Config> apnRecord) {
+ apnRecord->password = inputText->getText();
+ };
+ onLoadCallback = [&](std::shared_ptr<packet_data::APN::Config> apnRecord) {
+ inputText->setText(apnRecord->password);
+ };
+ onEmptyCallback = [&]() { return inputText->isEmpty(); };
+ }
+
+ void ApnInputWidget::authtypeHandler()
+ {
+ titleLabel->setText(utils::localize.get("app_settings_apn_authtype"));
+ inputText->setTextType(TextType::SingleLine);
+ onSaveCallback = [&](std::shared_ptr<packet_data::APN::Config> apnRecord) {
+ apnRecord->setAuthMethod(inputText->getText());
+ };
+ onLoadCallback = [&](std::shared_ptr<packet_data::APN::Config> apnRecord) {
+ inputText->setText(apnRecord->getAuthMethod());
+ };
+ onEmptyCallback = [&]() { return inputText->isEmpty(); };
+ }
+
+ void ApnInputWidget::apntypeHandler()
+ {
+ titleLabel->setText(utils::localize.get("app_settings_apn_apntype"));
+ inputText->setTextType(TextType::SingleLine);
+ onSaveCallback = [&](std::shared_ptr<packet_data::APN::Config> apnRecord) {
+ apnRecord->setApnType(inputText->getText());
+ };
+ onLoadCallback = [&](std::shared_ptr<packet_data::APN::Config> apnRecord) {
+ inputText->setText(apnRecord->getApnType());
+ };
+ onEmptyCallback = [&]() { return inputText->isEmpty(); };
+ }
+ void ApnInputWidget::protocolHandler()
+ {
+ titleLabel->setText(utils::localize.get("app_settings_apn_apnprotocol"));
+ inputText->setTextType(TextType::SingleLine);
+ onSaveCallback = [&](std::shared_ptr<packet_data::APN::Config> apnRecord) {
+ apnRecord->setApnProtocol(inputText->getText());
+ };
+ onLoadCallback = [&](std::shared_ptr<packet_data::APN::Config> apnRecord) {
+ inputText->setText(apnRecord->getApnProtocol());
+ };
+ onEmptyCallback = [&]() { return inputText->isEmpty(); };
+ }
+
+} /* namespace gui */
A module-apps/application-settings-new/widgets/ApnInputWidget.hpp => module-apps/application-settings-new/widgets/ApnInputWidget.hpp +44 -0
@@ 0,0 1,44 @@
+// 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 "application-settings-new/data/SettingsInternals.hpp"
+#include "application-settings-new//widgets/ApnListItem.hpp"
+
+#include <ListItem.hpp>
+#include <Text.hpp>
+#include <TextFixedSize.hpp>
+
+namespace gui
+{
+ class ApnInputWidget : public ApnListItem
+ {
+ settingsInternals::ListItemName listItemName;
+
+ public:
+ ApnInputWidget(settingsInternals::ListItemName listItemName,
+ std::function<void(const UTF8 &text)> bottomBarTemporaryMode = nullptr,
+ std::function<void()> bottomBarRestoreFromTemporaryMode = nullptr,
+ std::function<void()> selectSpecialCharacter = nullptr,
+ std::function<void()> contentChanged = nullptr,
+ unsigned int lines = 1);
+
+ private:
+ VBox *vBox = nullptr;
+ Label *titleLabel = nullptr;
+ TextFixedSize *inputText = nullptr;
+ std::function<void()> checkTextContent = nullptr;
+
+ void applyItemNameSpecificSettings();
+ auto onDimensionChanged(const BoundingBox &oldDim, const BoundingBox &newDim) -> bool override;
+ void nameHandler();
+ void apnHandler();
+ void usernameHandler();
+ void passwordNumberHandler();
+ void authtypeHandler();
+ void apntypeHandler();
+ void protocolHandler();
+ };
+
+} /* namespace gui */
A module-apps/application-settings-new/widgets/ApnListItem.hpp => module-apps/application-settings-new/widgets/ApnListItem.hpp +18 -0
@@ 0,0 1,18 @@
+// 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 "application-settings-new/data/SettingsItemData.hpp"
+
+namespace gui
+{
+ class ApnListItem : public ListItem
+ {
+ public:
+ std::function<void(std::shared_ptr<packet_data::APN::Config> apnRecord)> onSaveCallback = nullptr;
+ std::function<void(std::shared_ptr<packet_data::APN::Config> apnRecord)> onLoadCallback = nullptr;
+ std::function<bool()> onEmptyCallback = nullptr;
+ };
+
+} /* namespace gui */
M module-apps/application-settings-new/widgets/SettingsStyle.hpp => module-apps/application-settings-new/widgets/SettingsStyle.hpp +20 -0
@@ 28,7 28,18 @@ namespace style
inline constexpr auto before_noon = "AM";
inline constexpr auto after_noon = "PM";
} // namespace time
+
+ namespace apnInputWidget
+ {
+ inline constexpr uint32_t w = style::window::default_body_width;
+ inline constexpr uint32_t h = 63;
+ inline constexpr uint32_t title_label_h = 20;
+ inline constexpr uint32_t input_text_h = 37;
+ inline constexpr uint32_t span_size = 6;
+ inline constexpr int32_t underline_padding = 4;
+ } // namespace apnInputWidget
} // namespace widget
+
namespace window
{
namespace leftArrowImage
@@ 70,6 81,15 @@ namespace style
inline constexpr auto separator_h = 55;
} // namespace nightshift
+
+ namespace newApn
+ {
+ inline constexpr uint32_t x = style::window::default_left_margin;
+ inline constexpr uint32_t y = style::header::height;
+ inline constexpr uint32_t w = style::listview::body_width_with_scroll;
+ inline constexpr uint32_t h = style::window_height - y - style::footer::height;
+ } // namespace newApn
+
} // namespace window
}; // namespace settings
} // namespace style
M module-apps/application-settings-new/windows/APNSettingsWindow.cpp => module-apps/application-settings-new/windows/APNSettingsWindow.cpp +6 -3
@@ 4,6 4,7 @@
#include "APNSettingsWindow.hpp"
#include "application-settings-new/ApplicationSettings.hpp"
#include "application-settings-new/widgets/SettingsStyle.hpp"
+#include "application-settings-new/data/SettingsItemData.hpp"
#include "OptionSetting.hpp"
#include <InputEvent.hpp>
@@ 18,15 19,17 @@ namespace gui
auto APNSettingsWindow::onInput(const InputEvent &inputEvent) -> bool
{
-
if (inputEvent.isShortPress()) {
if (inputEvent.is(KeyCode::KEY_LEFT)) {
- // switch to new/edit APN window
+ auto apnRecord = std::make_shared<packet_data::APN::Config>();
+ std::unique_ptr<gui::SwitchData> data = std::make_unique<ApnItemData>(apnRecord);
+ application->switchWindow(gui::window::name::new_apn, gui::ShowMode::GUI_SHOW_INIT, std::move(data));
+ return true;
}
}
-
return AppWindow::onInput(inputEvent);
}
+
void APNSettingsWindow::buildInterface()
{
setTitle(utils::localize.get("app_settings_network_apn_settings"));
A module-apps/application-settings-new/windows/NewApnWindow.cpp => module-apps/application-settings-new/windows/NewApnWindow.cpp +116 -0
@@ 0,0 1,116 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#include "NewApnWindow.hpp"
+#include "application-settings-new/ApplicationSettings.hpp"
+
+#include <Dialog.hpp>
+#include <messages/DialogMetadataMessage.hpp>
+
+namespace gui
+{
+
+ NewApnWindow::NewApnWindow(app::Application *app)
+ : AppWindow(app, gui::window::name::new_apn), newApnModel{std::make_shared<NewApnModel>(app)}
+ {
+ buildInterface();
+ }
+
+ void NewApnWindow::rebuild()
+ {
+ destroyInterface();
+ buildInterface();
+ }
+
+ void NewApnWindow::buildInterface()
+ {
+ AppWindow::buildInterface();
+
+ bottomBar->setText(BottomBar::Side::CENTER, utils::localize.get(style::strings::common::save));
+ bottomBar->setText(BottomBar::Side::RIGHT, utils::localize.get(style::strings::common::back));
+
+ setTitle(utils::localize.get("app_settings_new_edit_apn"));
+
+ list = new gui::ListView(this,
+ style::settings::window::newApn::x,
+ style::settings::window::newApn::y,
+ style::settings::window::newApn::w,
+ style::settings::window::newApn::h,
+ newApnModel);
+ setFocusItem(list);
+ }
+
+ void NewApnWindow::destroyInterface()
+ {
+ erase();
+ }
+
+ void NewApnWindow::onBeforeShow(ShowMode mode, SwitchData *data)
+ {
+ if (mode != ShowMode::GUI_SHOW_RETURN) {
+ newApnModel->clearData();
+ }
+
+ if (mode == ShowMode::GUI_SHOW_INIT) {
+ list->rebuildList();
+ }
+
+ if (apn != nullptr) {
+ newApnModel->loadData(apn);
+ }
+ }
+
+ auto NewApnWindow::handleSwitchData(SwitchData *data) -> bool
+ {
+ setSaveButtonVisible(false);
+
+ if (data == nullptr) {
+ return false;
+ }
+
+ auto *item = dynamic_cast<ApnItemData *>(data);
+ if (item == nullptr) {
+ return false;
+ }
+
+ apn = item->getApn();
+ if (apn == nullptr) {
+ apn = std::make_shared<packet_data::APN::Config>();
+ return true;
+ }
+
+ return true;
+ }
+
+ void NewApnWindow::setSaveButtonVisible(bool visible)
+ {
+ bottomBar->setActive(BottomBar::Side::CENTER, visible);
+ }
+
+ auto NewApnWindow::onInput(const InputEvent &inputEvent) -> bool
+ {
+ if (inputEvent.isShortPress()) {
+ if (inputEvent.is(KeyCode::KEY_ENTER)) {
+ if (apn != nullptr)
+ newApnModel->saveData(apn);
+ verifyAndSave();
+ return true;
+ }
+ }
+
+ return AppWindow::onInput(inputEvent);
+ }
+
+ auto NewApnWindow::verifyAndSave() -> bool
+ {
+ if (apn != nullptr) {
+ newApnModel->apnSendRecord(*apn);
+ LOG_DEBUG("APN record saved : \"%s\" ", apn->apn.c_str());
+ }
+ else
+ LOG_DEBUG("APN record not found");
+
+ return true;
+ }
+
+} // namespace gui
A module-apps/application-settings-new/windows/NewApnWindow.hpp => module-apps/application-settings-new/windows/NewApnWindow.hpp +33 -0
@@ 0,0 1,33 @@
+// 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 "application-settings-new/models/NewApnModel.hpp"
+
+#include <AppWindow.hpp>
+#include <ListView.hpp>
+#include <Text.hpp>
+
+namespace gui
+{
+ class NewApnWindow : public AppWindow
+ {
+ public:
+ NewApnWindow(app::Application *app);
+
+ private:
+ auto onInput(const InputEvent &inputEvent) -> bool override;
+ void onBeforeShow(ShowMode mode, SwitchData *data) override;
+ auto handleSwitchData(SwitchData *data) -> bool override;
+ void rebuild() override;
+ void buildInterface() override;
+ void destroyInterface() override;
+ auto verifyAndSave() -> bool;
+ void setSaveButtonVisible(bool visible);
+ std::shared_ptr<packet_data::APN::Config> apn;
+ std::shared_ptr<NewApnModel> newApnModel;
+ gui::ListView *list = nullptr;
+ };
+
+} /* namespace gui */
M module-services/service-cellular/ServiceCellular.cpp => module-services/service-cellular/ServiceCellular.cpp +5 -5
@@ 297,12 297,12 @@ void ServiceCellular::registerMessageHandlers()
return handleCellularGetActiveContextsMessage(msg);
});
- connect(typeid(CellularGetAPNMessage), [&](sys::Message *request) -> sys::MessagePointer {
- connect(typeid(CellularGetCurrentOperatorMessage), [&](sys::Message *request) -> sys::MessagePointer {
- auto msg = static_cast<CellularGetCurrentOperatorMessage *>(request);
- return handleCellularGetCurrentOperator(msg);
- });
+ connect(typeid(CellularGetCurrentOperatorMessage), [&](sys::Message *request) -> sys::MessagePointer {
+ auto msg = static_cast<CellularGetCurrentOperatorMessage *>(request);
+ return handleCellularGetCurrentOperator(msg);
+ });
+ connect(typeid(CellularGetAPNMessage), [&](sys::Message *request) -> sys::MessagePointer {
auto msg = static_cast<CellularGetAPNMessage *>(request);
return handleCellularGetAPNMessage(msg);
});
M module-services/service-cellular/service-cellular/PacketDataTypes.hpp => module-services/service-cellular/service-cellular/PacketDataTypes.hpp +64 -2
@@ 5,6 5,10 @@
#include <string>
#include <memory>
+#include <unordered_map>
+#include <map>
+
+#include <Utils.hpp>
namespace packet_data
{
@@ 22,10 26,11 @@ namespace packet_data
*/
enum class APNType
{
- Default, ///< for data traffic
+ Default, ///< only one APN is set as default
IMS, ///< IP Multimedia Subsystem for eg VoLTE
MMS, ///< for MMS service
- Fota ///< for Firmware Update
+ Fota, ///< for Firmware Update
+ Internet //< for data traffic
};
/**
@@ 81,6 86,63 @@ namespace packet_data
std::string password;
std::string ip; /// set after connection
+ std::string getAuthMethod()
+ {
+ return utils::enumToString(authMethod);
+ }
+
+ void setAuthMethod(const std::string &str)
+ {
+ if (str == "NONE")
+ authMethod = AuthMethod::NONE;
+ else if (str == "AUTO")
+ authMethod = AuthMethod::AUTO;
+ else if (str == "CHAP")
+ authMethod = AuthMethod::CHAP;
+ else if (str == "PAP")
+ authMethod = AuthMethod::PAP;
+ else
+ authMethod = AuthMethod::NONE;
+ }
+
+ std::string getApnType()
+ {
+ return utils::enumToString(apnType);
+ }
+
+ void setApnType(const std::string &str)
+ {
+ if (str == "Default")
+ apnType = APNType::Default;
+ else if (str == "Fota")
+ apnType = APNType::Fota;
+ else if (str == "IMS")
+ apnType = APNType::IMS;
+ else if (str == "Internet")
+ apnType = APNType::Internet;
+ else if (str == "MMS")
+ apnType = APNType::MMS;
+ else
+ apnType = APNType::Internet;
+ }
+
+ std::string getApnProtocol()
+ {
+ return utils::enumToString(contextType);
+ }
+
+ void setApnProtocol(const std::string &str)
+ {
+ if (str == "ipv4")
+ contextType = ContextType::ipv4;
+ else if (str == "ipv6")
+ contextType = ContextType::ipv6;
+ else if (str == "ipv4v6")
+ contextType = ContextType::ipv4v6;
+ else
+ contextType = ContextType::ipv4;
+ }
+
bool isEmpty() const noexcept
{
return apn.empty();