M module-apps/application-notes/windows/NoteEditWindow.cpp => module-apps/application-notes/windows/NoteEditWindow.cpp +2 -2
@@ 156,7 156,7 @@ namespace app::notes
std::make_unique<gui::OptionsWindowOptions>(noteEditOptions(application, edit)));
}
}
- if (isCurrentTextDifferentThanSaved() &&
+ if (isAnyUnsavedUserDataInWindow() &&
(inputEvent.isShortRelease(gui::KeyCode::KEY_RF) || inputEvent.isLongRelease(gui::KeyCode::KEY_RF))) {
// Show a popup warning about possible data loss
@@ 189,7 189,7 @@ namespace app::notes
return (edit != nullptr) ? edit->isEmpty() : true;
}
- bool NoteEditWindow::isCurrentTextDifferentThanSaved()
+ bool NoteEditWindow::isAnyUnsavedUserDataInWindow() const
{
return notesRecord->snippet != edit->getText();
}
M module-apps/application-notes/windows/NoteEditWindow.hpp => module-apps/application-notes/windows/NoteEditWindow.hpp +1 -1
@@ 42,7 42,7 @@ namespace app::notes
void setCharactersCount(std::uint32_t count);
void setNoteText(const UTF8 &text);
void saveNote();
- bool isCurrentTextDifferentThanSaved();
+ bool isAnyUnsavedUserDataInWindow() const override;
std::unique_ptr<NoteEditWindowContract::Presenter> presenter;
std::shared_ptr<NotesRecord> notesRecord;
M module-apps/application-phonebook/windows/PhonebookNewContact.cpp => module-apps/application-phonebook/windows/PhonebookNewContact.cpp +4 -3
@@ 151,7 151,7 @@ namespace gui
return true;
}
else if (!inputEvent.isShortRelease(KeyCode::KEY_RF) || !shouldCurrentAppBeIgnoredOnSwitchBack()) {
- if (areUnsavedChanges()) {
+ if (isAnyUnsavedUserDataInWindow()) {
if (inputEvent.isShortRelease(gui::KeyCode::KEY_RF) || inputEvent.isLongRelease(gui::KeyCode::KEY_RF)) {
showDialogUnsavedChanges([this]() {
application->returnToPreviousWindow();
@@ 171,7 171,7 @@ namespace gui
: true;
};
- if (areUnsavedChanges()) {
+ if (isAnyUnsavedUserDataInWindow()) {
showDialogUnsavedChanges(returnWhenCurrentAppShouldBeIgnoredOnSwitchBack);
return true;
}
@@ 336,7 336,8 @@ namespace gui
contactByID->front().primaryName.empty() and contactByID->front().alternativeName.empty() and
contactByID->front().numbers.empty();
}
- bool PhonebookNewContact::areUnsavedChanges() const
+
+ bool PhonebookNewContact::isAnyUnsavedUserDataInWindow() const
{
return newContactModel->isAnyUnsavedChange(contact);
}
M module-apps/application-phonebook/windows/PhonebookNewContact.hpp => module-apps/application-phonebook/windows/PhonebookNewContact.hpp +1 -1
@@ 43,7 43,7 @@ namespace gui
void setSaveButtonVisible(bool visible);
void showContactDeletedNotification();
bool checkIfContactWasDeletedDuringEditProcess() const;
- bool areUnsavedChanges() const;
+ bool isAnyUnsavedUserDataInWindow() const override;
std::shared_ptr<ContactRecord> contact = nullptr;
std::shared_ptr<NewContactModel> newContactModel = nullptr;
M module-apps/apps-common/ApplicationCommon.cpp => module-apps/apps-common/ApplicationCommon.cpp +5 -0
@@ 1015,6 1015,11 @@ namespace app
return window;
}
+ std::size_t ApplicationCommon::getSizeOfWindowsStack()
+ {
+ return windowsStack().getSize();
+ }
+
bool ApplicationCommon::isCurrentWindow(const std::string &windowName) const noexcept
{
if (const auto &window = windowsStack().get(topWindow); window.has_value()) {
M module-apps/apps-common/ApplicationCommon.hpp => module-apps/apps-common/ApplicationCommon.hpp +3 -0
@@ 379,6 379,9 @@ namespace app
/// if there is none - returns default window
/// @ingrup AppWindowStack
gui::AppWindow *getCurrentWindow();
+ /// getter for size of windows stack
+ /// @ingrup AppWindowStack
+ std::size_t getSizeOfWindowsStack();
/// @ingrup AppWindowStack
bool isCurrentWindow(const std::string &windowName) const noexcept;
bool isPreviousWindow(const std::string &windowName) const noexcept;
M module-apps/apps-common/WindowsStack.cpp => module-apps/apps-common/WindowsStack.cpp +5 -1
@@ 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
#include "WindowsStack.hpp"
@@ 135,5 135,9 @@ namespace app
std::advance(it, 1);
}
}
+ std::size_t WindowsStack::getSize() const noexcept
+ {
+ return stack.size();
+ }
} // namespace app
M module-apps/apps-common/WindowsStack.hpp => module-apps/apps-common/WindowsStack.hpp +2 -1
@@ 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
@@ 51,6 51,7 @@ namespace app
std::map<std::string, std::unique_ptr<gui::AppWindow>>::const_iterator begin() const;
std::map<std::string, std::unique_ptr<gui::AppWindow>>::const_iterator end() const;
[[nodiscard]] bool isEmpty() const noexcept;
+ [[nodiscard]] std::size_t getSize() const noexcept;
/// add window on top of stack
void push(const std::string &name,
M => +41 -3
@@ 21,12 21,50 @@ namespace gui
metadata.text = utils::translate("tethering_enable_question");
metadata.icon = "tethering_128px_W_G";
metadata.action = [this]() {
application->bus.sendUnicast(std::make_shared<sys::TetheringEnabledResponse>(),
service::name::system_manager);
app::manager::Controller::sendAction(application, app::manager::actions::Home);
// check if there is any unsaved data in any window in stack
bool IsDataUnsaved = false;
auto windowStackSize = application->getSizeOfWindowsStack();
for (auto windowOnStackNumber = windowStackSize; windowOnStackNumber > 0; windowOnStackNumber--) {
if (const auto &previousWindowName = application->getPreviousWindow(windowOnStackNumber);
previousWindowName.has_value()) {
const auto previousWindow = application->getWindow(previousWindowName.value());
IsDataUnsaved = previousWindow->isAnyUnsavedUserDataInWindow() ? true : IsDataUnsaved;
}
}
// what is the expected action when YES is selected
auto onYesAction = [this]() {
application->bus.sendUnicast(std::make_shared<sys::TetheringEnabledResponse>(),
service::name::system_manager);
app::manager::Controller::sendAction(application, app::manager::actions::Home);
return true;
};
// if there are any unsaved changes, open the appropriate popup, otherwise proceed as usual
if (IsDataUnsaved) {
showDialogUnsavedChanges(onYesAction);
return true;
}
onYesAction();
return true;
};
auto msg = std::make_unique<DialogMetadataMessage>(std::move(metadata));
DialogYesNo::onBeforeShow(mode, msg.get());
}
void TetheringConfirmationPopup::showDialogUnsavedChanges(std::function<bool()> whatToDoOnYes)
{
// Show a popup warning about possible data loss
auto metaData = std::make_unique<gui::DialogMetadataMessage>(
gui::DialogMetadata{utils::translate("unsaved_changes"),
"delete_128px_W_G",
utils::translate("exit_without_saving"),
"",
[=]() -> bool {
application->returnToPreviousWindow(); // To exit this popup
return whatToDoOnYes();
}});
application->switchWindow(gui::window::name::dialog_yes_no, std::move(metaData));
}
} // namespace gui
M => +8 -1
@@ 1,4 1,4 @@
// Copyright (c) 2017-2021, 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
@@ 6,6 6,10 @@
#include <string>
#include "Dialog.hpp"
namespace gui::window::name
{
inline constexpr auto dialog_yes_no = "DialogYesNo";
} // namespace gui::window::name
namespace gui
{
@@ 15,5 19,8 @@ namespace gui
TetheringConfirmationPopup(app::ApplicationCommon *app, const std::string &name);
void onBeforeShow(ShowMode mode, SwitchData *data) override;
private:
void showDialogUnsavedChanges(std::function<bool()> whatToDoOnYes);
};
}; // namespace gui
M module-gui/gui/widgets/Window.hpp => module-gui/gui/widgets/Window.hpp +7 -1
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2021, 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
@@ 89,6 89,12 @@ namespace gui
{
return name;
}
+
+ /// used for get info about any unsaved user data changes
+ virtual bool isAnyUnsavedUserDataInWindow() const
+ {
+ return false;
+ }
};
} /* namespace gui */
M pure_changelog.md => pure_changelog.md +1 -0
@@ 44,6 44,7 @@
* Fixed the ability to create a contact with the same primary and secondary phone number, which resulted in mismatching
* Fixed losing drafted message and recipient number in new message windows
* Fixed misleading "Save" button behavior in "Date and time" window
+* Fixed losing unsaved user data when tethering is switching on
## [1.7.2 2023-07-28]