From cc9365517846f26d7b99916f9c749b323096b2ba Mon Sep 17 00:00:00 2001 From: Oskar Chodowicz Date: Fri, 12 Jul 2019 16:42:45 +0200 Subject: [PATCH] Accessories Switches Pages in mvp Change-Id: If2b5f42d76aa2ae34fdf6be43191d9c32c76c125 --- src/model/AddAccessoriesSwitchesPageModel.cpp | 50 +++++++++++++ src/model/AddAccessoriesSwitchesPageModel.hpp | 24 ++++++ src/model/UpdateAccessoriesSwitchPageModel.cpp | 48 ++++++++++++ src/model/UpdateAccessoriesSwitchPageModel.hpp | 20 +++++ .../AddAccessoriesSwitchesPagePresenter.cpp | 35 +++++++++ .../AddAccessoriesSwitchesPagePresenter.hpp | 19 +++++ src/presenter/AddSwitchPagePresenter.cpp | 3 +- .../AlreadyMappedSwitchModalPresenter.cpp | 8 ++ .../AlreadyMappedSwitchModalPresenter.hpp | 12 +++ src/presenter/AppContext.cpp | 18 ++++- src/presenter/AppContext.hpp | 1 + src/presenter/EntryNameModalPresenter.cpp | 20 +++++ src/presenter/EntryNameModalPresenter.hpp | 15 ++++ src/presenter/LabelPresenter.hpp | 16 ++++ src/presenter/ListPresenter.cpp | 18 ----- src/presenter/ListPresenter.hpp | 6 -- src/presenter/ModalPresenter.cpp | 5 ++ src/presenter/ModalPresenter.hpp | 2 + src/presenter/Presenter.cpp | 20 +++++ src/presenter/Presenter.hpp | 7 ++ src/presenter/RemoveSwitchesModalPresenter.cpp | 3 +- src/presenter/SelectActionPagePresenter.cpp | 16 ++-- src/presenter/SelectActionPagePresenter.hpp | 4 +- src/presenter/SwitchesPagePresenter.cpp | 12 +-- src/presenter/SwitchesPagePresenter.hpp | 2 +- .../UpdateAccessoriesSwitchPagePresenter.cpp | 61 +++++++++++++++ .../UpdateAccessoriesSwitchPagePresenter.hpp | 24 ++++++ src/service/DBus.cpp | 8 +- src/service/DBus.hpp | 39 +++++++--- src/ui/Entry.cpp | 10 +++ src/ui/Entry.hpp | 2 + src/ui/GenlistItem.cpp | 1 + src/view/LabelView.cpp | 27 +++++++ src/view/LabelView.hpp | 20 +++++ src/view/ListView.cpp | 87 ++++++++++++++++------ src/view/ListView.hpp | 7 ++ src/view/ModalView.cpp | 81 +++++++++++++++----- src/view/ModalView.hpp | 7 ++ src/view/NavigationContext.cpp | 7 ++ 39 files changed, 668 insertions(+), 97 deletions(-) create mode 100644 src/model/AddAccessoriesSwitchesPageModel.cpp create mode 100644 src/model/AddAccessoriesSwitchesPageModel.hpp create mode 100644 src/model/UpdateAccessoriesSwitchPageModel.cpp create mode 100644 src/model/UpdateAccessoriesSwitchPageModel.hpp create mode 100644 src/presenter/AddAccessoriesSwitchesPagePresenter.cpp create mode 100644 src/presenter/AddAccessoriesSwitchesPagePresenter.hpp create mode 100644 src/presenter/AlreadyMappedSwitchModalPresenter.cpp create mode 100644 src/presenter/AlreadyMappedSwitchModalPresenter.hpp create mode 100644 src/presenter/EntryNameModalPresenter.cpp create mode 100644 src/presenter/EntryNameModalPresenter.hpp create mode 100644 src/presenter/LabelPresenter.hpp create mode 100644 src/presenter/UpdateAccessoriesSwitchPagePresenter.cpp create mode 100644 src/presenter/UpdateAccessoriesSwitchPagePresenter.hpp create mode 100644 src/view/LabelView.cpp create mode 100644 src/view/LabelView.hpp diff --git a/src/model/AddAccessoriesSwitchesPageModel.cpp b/src/model/AddAccessoriesSwitchesPageModel.cpp new file mode 100644 index 0000000..5c686b7 --- /dev/null +++ b/src/model/AddAccessoriesSwitchesPageModel.cpp @@ -0,0 +1,50 @@ +#include "AddAccessoriesSwitchesPageModel.hpp" + +#include "UniversalSwitchConstants.hpp" + +AddAccessoriesSwitchesPageModel::AddAccessoriesSwitchesPageModel() +{ + dBusClient_ = DBus::DBusClient{BUS, PATH, IFACE, DBus::ConnectionType::SESSION}; +} + +AddAccessoriesSwitchesPageModel::~AddAccessoriesSwitchesPageModel() +{ + cancelCaptureSwitch(); +} + +void AddAccessoriesSwitchesPageModel::captureSwitch(std::function onCapture, std::string providerId) +{ + dBusClient_.method("captureSwitch").timeout(DBus::InfinitiveTimeout).asyncCall([onCapture](DBus::ValueOrError msg) { + if (msg) { + onCapture(std::get<0>(msg)); + } else { + ERROR("Error on function captureSwitch asyncCall"); + ERROR("failed '%s'", msg.getError().message.c_str()); + } + }, + providerId); +} + +void AddAccessoriesSwitchesPageModel::cancelCaptureSwitch() +{ + auto reply = dBusClient_.method()>("cancelCaptureSwitch").call(); + if (!reply) { + ERROR("Error on function cancelCaptureSwitch call"); + ERROR("%s", reply.getError().message.c_str()); + } +} + +bool AddAccessoriesSwitchesPageModel::isConfigured(const std::string &switchId) +{ + auto reply = dBusClient_.method>>()>("getAllSwitchConfigurationItems").call(); + if (reply) { + for (auto &item : std::get<0>(reply)) + if (std::get<0>(item) == switchId) + return true; + } else { + ERROR("Error on function getAllSwitchConfigurationItems call"); + ERROR("%s", reply.getError().message.c_str()); + ASSERT(0, "unable to know that switch is configured"); + } + return false; +} diff --git a/src/model/AddAccessoriesSwitchesPageModel.hpp b/src/model/AddAccessoriesSwitchesPageModel.hpp new file mode 100644 index 0000000..0b0a9d9 --- /dev/null +++ b/src/model/AddAccessoriesSwitchesPageModel.hpp @@ -0,0 +1,24 @@ +#ifndef ADD_ACCESSORIES_SWITCHES_PAGE_MODEL_HPP +#define ADD_ACCESSORIES_SWITCHES_PAGE_MODEL_HPP + +#include "DBus.hpp" +#include "ObservableProperty.hpp" +#include "UniversalSwitchTypes.hpp" +#include "VConf.hpp" + +#include + +class AddAccessoriesSwitchesPageModel +{ + public: + AddAccessoriesSwitchesPageModel(); + ~AddAccessoriesSwitchesPageModel(); + void captureSwitch(std::function onCapture, std::string providerId); + void cancelCaptureSwitch(); + bool isConfigured(const std::string &switchId); + + private: + DBus::DBusClient dBusClient_; +}; + +#endif \ No newline at end of file diff --git a/src/model/UpdateAccessoriesSwitchPageModel.cpp b/src/model/UpdateAccessoriesSwitchPageModel.cpp new file mode 100644 index 0000000..07195c9 --- /dev/null +++ b/src/model/UpdateAccessoriesSwitchPageModel.cpp @@ -0,0 +1,48 @@ +#include "UpdateAccessoriesSwitchPageModel.hpp" + +#include "UniversalSwitchConstants.hpp" + +UpdateAccessoriesSwitchPageModel::UpdateAccessoriesSwitchPageModel() +{ +} + +SwitchConfigurationItem UpdateAccessoriesSwitchPageModel::getDetailsForSwitchConfigurationItem(const std::string &switchId) +{ + auto reply = DBus::DBusClient{BUS, PATH, IFACE, DBus::ConnectionType::SESSION}.method>>()>("getAllSwitchConfigurationItems").call(); + if (reply) { + for (auto &item : std::get<0>(reply)) + if (std::get<0>(item) == switchId) + return SwitchConfigurationItem{std::get<0>(item), std::get<1>(item), std::get<2>(item)}; + } else { + ERROR("Error on function getAllSwitchConfigurationItems call"); + ERROR("%s", reply.getError().message.c_str()); + } + return {}; +} + +InfoType UpdateAccessoriesSwitchPageModel::getActivityDetails(const std::string &activityId) +{ + auto dBusClient = DBus::DBusClient{BUS, PATH, IFACE, DBus::ConnectionType::SESSION}; + auto reply = dBusClient.method>>()>("getBindableActivityTypes").call(); + if (reply) { + for (auto &activity : std::get<0>(reply)) + if (std::get<0>(activity) == activityId) + return InfoType{std::get<0>(activity), std::get<1>(activity), std::get<2>(activity)}; + } else { + ERROR("Error on function getBindableActivityTypes call"); + ERROR("%s", reply.getError().message.c_str()); + } + return {}; +} + +void UpdateAccessoriesSwitchPageModel::updateSwitch(const SwitchConfigurationItem &item) +{ + auto dBusClient = DBus::DBusClient{BUS, PATH, IFACE, DBus::ConnectionType::SESSION}; + auto reply = dBusClient.method(std::string, std::string, std::string)>("updateSwitchConfigurationItem").call(item.switchId, item.userName, item.activityType); + if (reply) + DEBUG("Switch: %s updated successfully", item.switchId.c_str()); + else { + ERROR("Error on function updateSwitchConfigurationItem call"); + ERROR("%s", reply.getError().message.c_str()); + } +} \ No newline at end of file diff --git a/src/model/UpdateAccessoriesSwitchPageModel.hpp b/src/model/UpdateAccessoriesSwitchPageModel.hpp new file mode 100644 index 0000000..24fe67a --- /dev/null +++ b/src/model/UpdateAccessoriesSwitchPageModel.hpp @@ -0,0 +1,20 @@ +#ifndef UPDATE_ACCESSORIES_SWITCH_PAGE_MODEL_HPP +#define UPDATE_ACCESSORIES_SWITCH_PAGE_MODEL_HPP + +#include "DBus.hpp" +#include "ObservableProperty.hpp" +#include "UniversalSwitchTypes.hpp" +#include "VConf.hpp" + +#include + +class UpdateAccessoriesSwitchPageModel +{ + public: + UpdateAccessoriesSwitchPageModel(); + SwitchConfigurationItem getDetailsForSwitchConfigurationItem(const std::string &switchId); + InfoType getActivityDetails(const std::string &actionId); + void updateSwitch(const SwitchConfigurationItem &item); +}; + +#endif \ No newline at end of file diff --git a/src/presenter/AddAccessoriesSwitchesPagePresenter.cpp b/src/presenter/AddAccessoriesSwitchesPagePresenter.cpp new file mode 100644 index 0000000..1941772 --- /dev/null +++ b/src/presenter/AddAccessoriesSwitchesPagePresenter.cpp @@ -0,0 +1,35 @@ +#include "AddAccessoriesSwitchesPagePresenter.hpp" + +#include "AlreadyMappedSwitchModalPresenter.hpp" +#include "AppContext.hpp" +#include "EntryNameModalPresenter.hpp" +#include "Singleton.hpp" +#include "UniversalSwitchConstants.hpp" + +AddAccessoriesSwitchesPagePresenter::AddAccessoriesSwitchesPagePresenter() +{ + setTitle("IDS_ACCS_UNIVERSAL_SWITCH_ADD_SWITCH_ACCESSORIES_TITLE"); + labelText_ = "IDS_ACCS_UNIVERSAL_SWITCH_ADD_SWITCH_ACCESSORIES_DESC"; +} + +void AddAccessoriesSwitchesPagePresenter::onTop() +{ + model_.captureSwitch([this](auto switchId) { + this->onSwitchCapture(switchId); + }, + ACCESSIBILITY_UNIVERSAL_SWITCH_ACCESSORIES_SWITCH_PROVIDER); +} + +void AddAccessoriesSwitchesPagePresenter::notOnTop() +{ + model_.cancelCaptureSwitch(); +} + +void AddAccessoriesSwitchesPagePresenter::onSwitchCapture(const std::string &switchId) +{ + notOnTop(); + if (model_.isConfigured(switchId)) + Singleton::instance().pushModal(std::make_unique()); + else + Singleton::instance().pushModal(std::make_unique(switchId)); +} diff --git a/src/presenter/AddAccessoriesSwitchesPagePresenter.hpp b/src/presenter/AddAccessoriesSwitchesPagePresenter.hpp new file mode 100644 index 0000000..0610257 --- /dev/null +++ b/src/presenter/AddAccessoriesSwitchesPagePresenter.hpp @@ -0,0 +1,19 @@ +#ifndef ADD_ACCESSORIES_SWITCHES_PAGE_PRESENTER +#define ADD_ACCESSORIES_SWITCHES_PAGE_PRESENTER + +#include "AddAccessoriesSwitchesPageModel.hpp" +#include "LabelPresenter.hpp" + +class AddAccessoriesSwitchesPagePresenter : public LabelPresenter +{ + public: + AddAccessoriesSwitchesPagePresenter(); + + private: + void onTop() override; + void notOnTop() override; + void onSwitchCapture(const std::string &switchId); + AddAccessoriesSwitchesPageModel model_; +}; + +#endif \ No newline at end of file diff --git a/src/presenter/AddSwitchPagePresenter.cpp b/src/presenter/AddSwitchPagePresenter.cpp index cb0bd00..a7241b3 100644 --- a/src/presenter/AddSwitchPagePresenter.cpp +++ b/src/presenter/AddSwitchPagePresenter.cpp @@ -1,5 +1,6 @@ #include "AddSwitchPagePresenter.hpp" +#include "AddAccessoriesSwitchesPagePresenter.hpp" #include "AppContext.hpp" #include "CameraSwitchesPagePresenter.hpp" #include "SelectActionPagePresenter.hpp" @@ -55,7 +56,7 @@ void AddSwitchPagePresenter::createPageForScreenProvider() void AddSwitchPagePresenter::createPageForAccessoriesProvider() { - //Singleton::instance().push(std::make_unique()); + Singleton::instance().push(std::make_unique()); } void AddSwitchPagePresenter::createPageForCameraProvider() diff --git a/src/presenter/AlreadyMappedSwitchModalPresenter.cpp b/src/presenter/AlreadyMappedSwitchModalPresenter.cpp new file mode 100644 index 0000000..1d0c337 --- /dev/null +++ b/src/presenter/AlreadyMappedSwitchModalPresenter.cpp @@ -0,0 +1,8 @@ +#include "AlreadyMappedSwitchModalPresenter.hpp" + +AlreadyMappedSwitchModalPresenter::AlreadyMappedSwitchModalPresenter() +{ + setTitle("IDS_ACCS_UNIVERSAL_SWITCH_UNABLE_TO_ADD"); + text_ = "IDS_ACCS_UNIVERSAL_SWITCH_ALREADY_ADDED"; + cancelText_ = "IDS_ACCS_UNIVERSAL_SWITCH_OK"; +} diff --git a/src/presenter/AlreadyMappedSwitchModalPresenter.hpp b/src/presenter/AlreadyMappedSwitchModalPresenter.hpp new file mode 100644 index 0000000..f001cac --- /dev/null +++ b/src/presenter/AlreadyMappedSwitchModalPresenter.hpp @@ -0,0 +1,12 @@ +#ifndef ALREADY_MAPPED_SWITCH_MODAL_PRESENTER +#define ALREADY_MAPPED_SWITCH_MODAL_PRESENTER + +#include "ModalPresenter.hpp" + +class AlreadyMappedSwitchModalPresenter : public ModalPresenter +{ + public: + AlreadyMappedSwitchModalPresenter(); +}; + +#endif \ No newline at end of file diff --git a/src/presenter/AppContext.cpp b/src/presenter/AppContext.cpp index 57ca8be..d7c989c 100644 --- a/src/presenter/AppContext.cpp +++ b/src/presenter/AppContext.cpp @@ -16,7 +16,10 @@ AppContext::AppContext() void AppContext::push(std::unique_ptr presenter) { + if (presentersStack_.size() > 0) + presentersStack_.back()->notOnTop(); presentersStack_.push_back(std::move(presenter)); + presentersStack_.back()->onTop(); presenterToBroadcast_ = presentersStack_.back().get(); countOfPagesToPop_ = 1; notify(); @@ -33,13 +36,18 @@ void AppContext::pop(size_t countOfPagesToPop) else countOfPagesToPop_ = countOfPagesToPop; + if (presentersStack_.size() > 0) + presentersStack_.back()->notOnTop(); + for (auto i = 0u; i < countOfPagesToPop_; ++i) presentersStack_.pop_back(); - if (presentersStack_.empty()) + if (presentersStack_.empty()) { ui_app_exit(); - else + } else { + presentersStack_.back()->onTop(); notify(); + } } Presenter *AppContext::back() @@ -54,6 +62,8 @@ bool AppContext::empty() void AppContext::pushModal(std::unique_ptr presenter) { + if (presentersStack_.size() > 0) + presentersStack_.back()->notOnTop(); modalPresentersStack_.push_back(std::move(presenter)); modalPresenterToBroadcast_ = modalPresentersStack_.back().get(); notifyAboutModal(); @@ -61,9 +71,11 @@ void AppContext::pushModal(std::unique_ptr presenter) void AppContext::popModal() { + if (presentersStack_.size() > 0) + presentersStack_.back()->onTop(); + modalPresentersStack_.pop_back(); modalPresenterToBroadcast_ = nullptr; notifyAboutModal(); - modalPresentersStack_.pop_back(); } ModalPresenter *AppContext::modalsBack() diff --git a/src/presenter/AppContext.hpp b/src/presenter/AppContext.hpp index e34b812..7d6c2b3 100644 --- a/src/presenter/AppContext.hpp +++ b/src/presenter/AppContext.hpp @@ -25,6 +25,7 @@ class AppContext : public Observable, public Observable sharedPreferences; private: std::vector> presentersStack_; diff --git a/src/presenter/EntryNameModalPresenter.cpp b/src/presenter/EntryNameModalPresenter.cpp new file mode 100644 index 0000000..0ecec72 --- /dev/null +++ b/src/presenter/EntryNameModalPresenter.cpp @@ -0,0 +1,20 @@ +#include "EntryNameModalPresenter.hpp" + +#include "AppContext.hpp" +#include "SelectActionPagePresenter.hpp" +#include "Singleton.hpp" + +EntryNameModalPresenter::EntryNameModalPresenter(std::string switchId) +{ + setTitle("IDS_ACCS_UNIVERSAL_SWITCH_ADD_SWITCH"); + entryAction_ = addAction(std::make_unique("modalEntry", "IDS_ACCS_UNIVERSAL_SWITCH_ADD_SWITCH_NAME", std::function{})); + doneText_ = "IDS_ACCS_UNIVERSAL_SWITCH_SAVE"; + cancelText_ = "IDS_ACCS_UNIVERSAL_SWITCH_CANCEL"; + doneCb_ = [this, switchId]() { + auto switchUserName = this->entryAction_->title_.value(); + if (!switchUserName.empty()) { + Singleton::instance().popModal(); + Singleton::instance().push(std::make_unique(switchId, switchUserName, ChangeType::ADD, 2)); + } + }; +} \ No newline at end of file diff --git a/src/presenter/EntryNameModalPresenter.hpp b/src/presenter/EntryNameModalPresenter.hpp new file mode 100644 index 0000000..05999f7 --- /dev/null +++ b/src/presenter/EntryNameModalPresenter.hpp @@ -0,0 +1,15 @@ +#ifndef ENTRY_NAME_MODAL_PRESENTER_HPP +#define ENTRY_NAME_MODAL_PRESENTER_HPP + +#include "ModalPresenter.hpp" + +class EntryNameModalPresenter : public ModalPresenter +{ + public: + EntryNameModalPresenter(std::string switchId); + + private: + Action *entryAction_ = nullptr; +}; + +#endif \ No newline at end of file diff --git a/src/presenter/LabelPresenter.hpp b/src/presenter/LabelPresenter.hpp new file mode 100644 index 0000000..08ff134 --- /dev/null +++ b/src/presenter/LabelPresenter.hpp @@ -0,0 +1,16 @@ +#ifndef LABEL_PRESENTER +#define LABEL_PRESENTER + +#include "ObservableProperty.hpp" +#include "Presenter.hpp" + +class LabelPresenter : public Presenter +{ + public: + ObservableProperty labelText_; + + protected: + using Presenter::Presenter; +}; + +#endif \ No newline at end of file diff --git a/src/presenter/ListPresenter.cpp b/src/presenter/ListPresenter.cpp index 4b51eae..bae2f6b 100644 --- a/src/presenter/ListPresenter.cpp +++ b/src/presenter/ListPresenter.cpp @@ -5,24 +5,6 @@ const std::vector &ListPresenter::getListGroups() const return groups_; } -Action *ListPresenter::getAction(const std::string &actionId) const -{ - auto it = actions_.find(actionId); - if (it == actions_.end()) { - // DEBUG("Action with id: %s doesn't exist", actionId.c_str()); - return nullptr; - } - return it->second.get(); -} - -Action *ListPresenter::addAction(std::unique_ptr action) -{ - auto ret = actions_.insert_or_assign(action->actionId_, std::move(action)); - ASSERT(ret.second, "Action cannot be added"); - - return ret.first->second.get(); -} - void ListPresenter::setOnListUpdateCallback(std::function callback) { onListUpdate_ = std::move(callback); diff --git a/src/presenter/ListPresenter.hpp b/src/presenter/ListPresenter.hpp index 23737c7..aa28c21 100644 --- a/src/presenter/ListPresenter.hpp +++ b/src/presenter/ListPresenter.hpp @@ -1,19 +1,14 @@ #ifndef LIST_PRESENTER_HPP #define LIST_PRESENTER_HPP -#include "Action.hpp" #include "ListGroup.hpp" #include "Observable.hpp" #include "Presenter.hpp" -#include - class ListPresenter : public Presenter, public Observable<> { public: const std::vector &getListGroups() const; - Action *getAction(const std::string &actionId) const; - Action *addAction(std::unique_ptr action); void setOnListUpdateCallback(std::function callback); protected: @@ -21,7 +16,6 @@ class ListPresenter : public Presenter, public Observable<> std::function onListUpdate_; std::vector groups_; - std::unordered_map> actions_; }; #endif \ No newline at end of file diff --git a/src/presenter/ModalPresenter.cpp b/src/presenter/ModalPresenter.cpp index 5a14dc8..351142d 100644 --- a/src/presenter/ModalPresenter.cpp +++ b/src/presenter/ModalPresenter.cpp @@ -18,4 +18,9 @@ std::string ModalPresenter::getText() std::string ModalPresenter::getDoneText() { return doneText_; +} + +std::string ModalPresenter::getCancelText() +{ + return cancelText_; } \ No newline at end of file diff --git a/src/presenter/ModalPresenter.hpp b/src/presenter/ModalPresenter.hpp index 5cd77df..852eea8 100644 --- a/src/presenter/ModalPresenter.hpp +++ b/src/presenter/ModalPresenter.hpp @@ -10,6 +10,7 @@ class ModalPresenter : public Presenter std::function getCancelCb(); std::string getText(); std::string getDoneText(); + std::string getCancelText(); protected: using Presenter::Presenter; @@ -18,6 +19,7 @@ class ModalPresenter : public Presenter std::function cancelCb_; std::string text_; std::string doneText_; + std::string cancelText_; }; #endif \ No newline at end of file diff --git a/src/presenter/Presenter.cpp b/src/presenter/Presenter.cpp index 724f8f9..26ebeb0 100644 --- a/src/presenter/Presenter.cpp +++ b/src/presenter/Presenter.cpp @@ -24,3 +24,23 @@ void Presenter::onAppPause() void Presenter::onAppResume() {} + +void Presenter::onTop() +{} + +void Presenter::notOnTop() +{} + +Action *Presenter::getAction(const std::string &actionId) const +{ + auto it = actions_.find(actionId); + if (it == actions_.end()) { + return nullptr; + } + return it->second.get(); +} + +Action *Presenter::addAction(std::unique_ptr action) +{ + return actions_.insert_or_assign(action->actionId_, std::move(action)).first->second.get(); +} \ No newline at end of file diff --git a/src/presenter/Presenter.hpp b/src/presenter/Presenter.hpp index 47ad30d..f6e4ca6 100644 --- a/src/presenter/Presenter.hpp +++ b/src/presenter/Presenter.hpp @@ -1,10 +1,12 @@ #ifndef PRESENTER_HPP #define PRESENTER_HPP +#include "Action.hpp" #include "GenlistItem.hpp" #include "TranslatedString.hpp" #include +#include #include class Presenter @@ -17,12 +19,17 @@ class Presenter const std::function getOnPopCallback() const; virtual void onAppPause(); virtual void onAppResume(); + virtual void onTop(); + virtual void notOnTop(); + Action *getAction(const std::string &actionId) const; + Action *addAction(std::unique_ptr action); protected: Presenter(TranslatedString title = {}, std::function onPopCallback = {}); TranslatedString title_; std::function onPopCallback_; + std::unordered_map> actions_; }; #endif \ No newline at end of file diff --git a/src/presenter/RemoveSwitchesModalPresenter.cpp b/src/presenter/RemoveSwitchesModalPresenter.cpp index ad0f702..8bbc19f 100644 --- a/src/presenter/RemoveSwitchesModalPresenter.cpp +++ b/src/presenter/RemoveSwitchesModalPresenter.cpp @@ -10,10 +10,11 @@ RemoveSwitchesModalPresenter::RemoveSwitchesModalPresenter(std::vectoraddOrUpdateSwitchConfigurationItem(activity.id); + this->addOrUpdateSwitchConfigurationItem(activity.id, locally); }, - ListItem::WidgetType::radio)); + ListItem::WidgetType::radio, + std::function{}, + std::function{}, + activityId == activity.id)); } } -void SelectActionPagePresenter::addOrUpdateSwitchConfigurationItem(const std::string &activityType) +void SelectActionPagePresenter::addOrUpdateSwitchConfigurationItem(const std::string &activityType, bool locally) { switch (changeType_) { case ChangeType::ADD: model_.addSwitch({switchId_, userName_, activityType}); break; case ChangeType::UPDATE: - model_.updateSwitch({switchId_, userName_, activityType}); + if (locally) + Singleton::instance().sharedPreferences.insert_or_assign(switchId_, activityType); + else + model_.updateSwitch({switchId_, userName_, activityType}); break; default: ASSERT(0, "Unhandled change type"); diff --git a/src/presenter/SelectActionPagePresenter.hpp b/src/presenter/SelectActionPagePresenter.hpp index 5dbf896..0a0af5c 100644 --- a/src/presenter/SelectActionPagePresenter.hpp +++ b/src/presenter/SelectActionPagePresenter.hpp @@ -8,10 +8,10 @@ class SelectActionPagePresenter : public ListPresenter { public: - SelectActionPagePresenter(std::string switchId, std::string userName, ChangeType changeType, size_t countOfPagesToPop); + SelectActionPagePresenter(std::string switchId, std::string userName, ChangeType changeType, size_t countOfPagesToPop, std::string activityId = {}, bool locally = false); private: - void addOrUpdateSwitchConfigurationItem(const std::string &activityType); + void addOrUpdateSwitchConfigurationItem(const std::string &activityType, bool locally); const std::string switchId_; const std::string userName_; ChangeType changeType_; diff --git a/src/presenter/SwitchesPagePresenter.cpp b/src/presenter/SwitchesPagePresenter.cpp index 3db4552..265dfb8 100644 --- a/src/presenter/SwitchesPagePresenter.cpp +++ b/src/presenter/SwitchesPagePresenter.cpp @@ -5,6 +5,7 @@ #include "RemoveSwitchesPagePresenter.hpp" #include "SelectActionPagePresenter.hpp" #include "UniversalSwitchConstants.hpp" +#include "UpdateAccessoriesSwitchPagePresenter.hpp" SwitchesPagePresenter::SwitchesPagePresenter() { @@ -35,7 +36,7 @@ void SwitchesPagePresenter::addItemsToList() oneSwitch.userName, model_.getActivityName(oneSwitch.activityType), [this, oneSwitch](auto item) { - this->createUpdatePage(oneSwitch.switchId, oneSwitch.userName); + this->createUpdatePage(oneSwitch); })); } items.push_back(std::make_unique( @@ -51,18 +52,19 @@ void SwitchesPagePresenter::addItemsToList() ACCESSIBILITY_UNIVERSAL_SWITCH_PLUS_ICON)); } -void SwitchesPagePresenter::createUpdatePage(const std::string &switchId, const std::string &userName) +void SwitchesPagePresenter::createUpdatePage(const SwitchConfigurationItem &item) { - auto providerName = utils::stringSplitByDelimiter(switchId, '_')[0]; + auto providerName = utils::stringSplitByDelimiter(item.switchId, '_')[0]; if (providerName == ACCESSIBILITY_UNIVERSAL_SWITCH_SCREEN_SWITCH_PROVIDER) { - Singleton::instance().push(std::make_unique(switchId, userName, ChangeType::UPDATE, 0)); + Singleton::instance().push(std::make_unique(item.switchId, item.userName, ChangeType::UPDATE, 0, item.activityType)); return; } if (providerName == ACCESSIBILITY_UNIVERSAL_SWITCH_ACCESSORIES_SWITCH_PROVIDER) { + Singleton::instance().push(std::make_unique(item.switchId)); return; } if (providerName == ACCESSIBILITY_UNIVERSAL_SWITCH_CAMERA_SWITCH_PROVIDER) { - Singleton::instance().push(std::make_unique(switchId, userName, ChangeType::UPDATE, 0)); + Singleton::instance().push(std::make_unique(item.switchId, item.userName, ChangeType::UPDATE, 0, item.activityType)); return; } } diff --git a/src/presenter/SwitchesPagePresenter.hpp b/src/presenter/SwitchesPagePresenter.hpp index 8ba66de..cc39265 100644 --- a/src/presenter/SwitchesPagePresenter.hpp +++ b/src/presenter/SwitchesPagePresenter.hpp @@ -11,7 +11,7 @@ class SwitchesPagePresenter : public ListPresenter private: void addItemsToList(); - void createUpdatePage(const std::string &switchId, const std::string &userName); + void createUpdatePage(const SwitchConfigurationItem &item); void updateSwitchDeleteAction(); SwitchesPageModel model_; Action *deleteSwitchesAction_ = nullptr; diff --git a/src/presenter/UpdateAccessoriesSwitchPagePresenter.cpp b/src/presenter/UpdateAccessoriesSwitchPagePresenter.cpp new file mode 100644 index 0000000..f6b6ae4 --- /dev/null +++ b/src/presenter/UpdateAccessoriesSwitchPagePresenter.cpp @@ -0,0 +1,61 @@ +#include "UpdateAccessoriesSwitchPagePresenter.hpp" + +#include "AppContext.hpp" +#include "SelectActionPagePresenter.hpp" + +UpdateAccessoriesSwitchPagePresenter::UpdateAccessoriesSwitchPagePresenter(std::string switchId) : switchId_(std::move(switchId)) +{ + cancelAction_ = addAction(std::make_unique("cancelAction", + "IDS_ACCS_UNIVERSAL_SWITCH_CANCEL", + [this](auto action) { + Singleton::instance().pop(); + })); + saveAction_ = addAction(std::make_unique("saveAction", + "IDS_ACCS_UNIVERSAL_SWITCH_SAVE", + [this](auto action) { + if (!entryItem_->entryText_.value().empty()) { + model_.updateSwitch(SwitchConfigurationItem{switchId_, entryItem_->entryText_.value(), activityId_}); + Singleton::instance().pop(); + } + })); + groups_.emplace_back(""); + auto &items = groups_.back().items_; + + items.push_back(std::make_unique( + "IDS_ACCS_UNIVERSAL_SWITCH_NAME", + std::string{}, + std::function{}, + ListItem::WidgetType::entry)); + + entryItem_ = items.back().get(); + auto switchInfo = model_.getDetailsForSwitchConfigurationItem(switchId_); + entryItem_->entryText_ = switchInfo.userName; + activityId_ = switchInfo.activityType; + + items.push_back(std::make_unique( + "IDS_ACCS_UNIVERSAL_SWITCH_ACTION", + model_.getActivityDetails(switchInfo.activityType).name, + [this](auto item) { + Singleton::instance().push(std::make_unique(switchId_, entryItem_->entryText_.value(), ChangeType::UPDATE, 0, activityId_, true)); + }, + ListItem::WidgetType::none, + std::function{}, + std::function{}, + false)); + actionItem_ = items.back().get(); +} + +void UpdateAccessoriesSwitchPagePresenter::onTop() +{ + auto &sharedPreferences = Singleton::instance().sharedPreferences; + auto val = sharedPreferences.find(switchId_); + if (val != sharedPreferences.end()) { + activityId_ = val->second; + actionItem_->description_ = model_.getActivityDetails(activityId_).name; + } +} + +UpdateAccessoriesSwitchPagePresenter::~UpdateAccessoriesSwitchPagePresenter() +{ + Singleton::instance().sharedPreferences.erase(switchId_); +} \ No newline at end of file diff --git a/src/presenter/UpdateAccessoriesSwitchPagePresenter.hpp b/src/presenter/UpdateAccessoriesSwitchPagePresenter.hpp new file mode 100644 index 0000000..45f3c6a --- /dev/null +++ b/src/presenter/UpdateAccessoriesSwitchPagePresenter.hpp @@ -0,0 +1,24 @@ +#ifndef UPDATE_ACCESSORIES_SWITCH_PAGE_PRESENTER +#define UPDATE_ACCESSORIES_SWITCH_PAGE_PRESENTER + +#include "ListPresenter.hpp" +#include "UpdateAccessoriesSwitchPageModel.hpp" + +class UpdateAccessoriesSwitchPagePresenter : public ListPresenter +{ + public: + UpdateAccessoriesSwitchPagePresenter(std::string switchId); + ~UpdateAccessoriesSwitchPagePresenter(); + + private: + void onTop() override; + std::string switchId_; + std::string activityId_; + Action *saveAction_ = nullptr; + Action *cancelAction_ = nullptr; + ListItem *entryItem_ = nullptr; + ListItem *actionItem_ = nullptr; + UpdateAccessoriesSwitchPageModel model_; +}; + +#endif \ No newline at end of file diff --git a/src/service/DBus.cpp b/src/service/DBus.cpp index 5495905..0720693 100644 --- a/src/service/DBus.cpp +++ b/src/service/DBus.cpp @@ -342,9 +342,9 @@ struct DefaultDBusWrapper : public DBusWrapper { return create(eldbus_proxy_method_call_new(get(proxy), funcName.c_str())); } - MessagePtr eldbus_proxy_send_and_block_impl(const ProxyPtr &proxy, const MessagePtr &msg) override + MessagePtr eldbus_proxy_send_and_block_impl(const ProxyPtr &proxy, const MessagePtr &msg, double timeout) override { - return create(eldbus_proxy_send_and_block(get(proxy), release(msg), ELDBUS_CALL_TIMEOUT)); + return create(eldbus_proxy_send_and_block(get(proxy), release(msg), timeout < 0 ? ELDBUS_TIMEOUT_INFINITE : timeout * 1000)); } bool eldbus_message_error_get_impl(const MessagePtr &msg, std::string &name, std::string &text) override { @@ -377,10 +377,10 @@ struct DefaultDBusWrapper : public DBusWrapper delete d; } - PendingPtr eldbus_proxy_send_impl(const ProxyPtr &proxy, const MessagePtr &msg, const SendCallback &callback) override + PendingPtr eldbus_proxy_send_impl(const ProxyPtr &proxy, const MessagePtr &msg, const SendCallback &callback, double timeout) override { auto cb = new SendCallback{callback}; - auto pending = eldbus_proxy_send(get(proxy), release(msg), callAsyncCb, cb, ELDBUS_CALL_TIMEOUT); + auto pending = eldbus_proxy_send(get(proxy), release(msg), callAsyncCb, cb, timeout < 0 ? ELDBUS_TIMEOUT_INFINITE : timeout * 1000); if (pending) { eldbus_pending_free_cb_add(pending, pendingFreeCb, cb); } else { diff --git a/src/service/DBus.hpp b/src/service/DBus.hpp index fc80948..5dcfed7 100644 --- a/src/service/DBus.hpp +++ b/src/service/DBus.hpp @@ -232,12 +232,12 @@ namespace DBus virtual MessageIterPtr eldbus_message_iter_get_and_next_by_type_impl(const MessageIterPtr &it, int type) = 0; virtual MessageIterPtr eldbus_message_iter_get_impl(const MessagePtr &it, bool write) = 0; virtual MessagePtr eldbus_proxy_method_call_new_impl(const ProxyPtr &proxy, const std::string &funcName) = 0; - virtual MessagePtr eldbus_proxy_send_and_block_impl(const ProxyPtr &proxy, const MessagePtr &msg) = 0; + virtual MessagePtr eldbus_proxy_send_and_block_impl(const ProxyPtr &proxy, const MessagePtr &msg, double timeout) = 0; virtual bool eldbus_message_error_get_impl(const MessagePtr &msg, std::string &name, std::string &text) = 0; virtual std::string eldbus_message_signature_get_impl(const MessagePtr &msg) = 0; using SendCallback = std::function; - virtual PendingPtr eldbus_proxy_send_impl(const ProxyPtr &proxy, const MessagePtr &msg, const SendCallback &callback) = 0; + virtual PendingPtr eldbus_proxy_send_impl(const ProxyPtr &proxy, const MessagePtr &msg, const SendCallback &callback, double timeout) = 0; virtual std::string eldbus_proxy_interface_get_impl(const ProxyPtr &) = 0; virtual void eldbus_proxy_signal_handler_add_impl(const ProxyPtr &proxy, const std::string &member, const std::function &cb) = 0; virtual std::string eldbus_message_iter_signature_get_impl(const MessageIterPtr &iter) = 0; @@ -605,10 +605,10 @@ namespace DBus MessageIterPtr eldbus_message_iter_get_and_next_by_type_impl(const MessageIterPtr &it, int type) override; MessageIterPtr eldbus_message_iter_get_impl(const MessagePtr &it, bool write) override; MessagePtr eldbus_proxy_method_call_new_impl(const ProxyPtr &proxy, const std::string &funcName) override; - MessagePtr eldbus_proxy_send_and_block_impl(const ProxyPtr &proxy, const MessagePtr &msg) override; + MessagePtr eldbus_proxy_send_and_block_impl(const ProxyPtr &proxy, const MessagePtr &msg, double timeout) override; bool eldbus_message_error_get_impl(const MessagePtr &msg, std::string &name, std::string &text) override; std::string eldbus_message_signature_get_impl(const MessagePtr &msg) override; - PendingPtr eldbus_proxy_send_impl(const ProxyPtr &proxy, const MessagePtr &msg, const SendCallback &callback) override; + PendingPtr eldbus_proxy_send_impl(const ProxyPtr &proxy, const MessagePtr &msg, const SendCallback &callback, double timeout) override; std::string eldbus_proxy_interface_get_impl(const ProxyPtr &) override; void eldbus_proxy_signal_handler_add_impl(const ProxyPtr &proxy, const std::string &member, const std::function &cb) override; std::string eldbus_message_iter_signature_get_impl(const MessageIterPtr &iter) override; @@ -2549,7 +2549,7 @@ namespace DBus DBusWrapper::ProxyPtr proxy, propertiesProxy; }; template - RETTYPE call(CallId callId, const ConnectionState &connectionState, bool property, const std::string &funcName, const ARGS &... args) + RETTYPE call(CallId callId, const ConnectionState &connectionState, bool property, double timeout, const std::string &funcName, const ARGS &... args) { const auto &proxy = property ? connectionState.propertiesProxy : connectionState.proxy; if (!proxy) { @@ -2565,7 +2565,7 @@ namespace DBus } detail::packValues(callId, msg, args...); - auto reply = DBUS_W->eldbus_proxy_send_and_block_impl(proxy, msg); + auto reply = DBUS_W->eldbus_proxy_send_and_block_impl(proxy, msg, timeout); DBUS_DEBUG("call %d: calling '%s' done", callId.id, funcName.c_str()); if (!reply) { DBUS_DEBUG("call %d: failed", callId.id); @@ -2581,7 +2581,7 @@ namespace DBus } template - void asyncCall(CallId callId, const ConnectionState &connectionState, bool property, const std::string &funcName, std::function callback, const ARGS &... args) + void asyncCall(CallId callId, const ConnectionState &connectionState, bool property, double timeout, const std::string &funcName, std::function callback, const ARGS &... args) { const auto &proxy = property ? connectionState.propertiesProxy : connectionState.proxy; if (!proxy) { @@ -2613,7 +2613,8 @@ namespace DBus callback(detail::unpackValues(callId, reply)); } } - }); + }, + timeout); if (pending) { DBUS_DEBUG("call %d: call sent", callId.id); } else { @@ -2749,6 +2750,11 @@ namespace DBus using ConnectionType = DBusWrapper::ConnectionType; + struct InfinitiveTimeout_ + { + }; + static constexpr InfinitiveTimeout_ InfinitiveTimeout; + /** * @brief Class representing client's end of DBUS connection * @@ -2756,6 +2762,7 @@ namespace DBus * Allows (synchronous and asynchronos) setting / getting properties. * Allows registering signals. */ + class DBusClient { /// \cond @@ -2829,6 +2836,7 @@ namespace DBus std::string funcName; std::string info; std::shared_ptr connectionInfo; + double timeout_ = 1.0; /// \endcond /** @@ -2844,9 +2852,20 @@ namespace DBus { detail::CallId callId; detail::displayDebugCallInfo(callId, funcName, info, connectionInfo->interfaceName); - return detail::call(callId, connectionState, false, funcName, args...); + return detail::call(callId, connectionState, false, timeout_, funcName, args...); + } + + auto &timeout(double d) + { + timeout_ = d; + return *this; } + auto &timeout(InfinitiveTimeout_) + { + timeout_ = -1; + return *this; + } /** * @brief Executes asynchronous call on DBUS's method * @@ -2860,7 +2879,7 @@ namespace DBus { detail::CallId callId; detail::displayDebugCallInfo(callId, funcName, info, connectionInfo->interfaceName); - detail::asyncCall(callId, connectionState, false, funcName, std::move(callback), args...); + detail::asyncCall(callId, connectionState, false, timeout_, funcName, std::move(callback), args...); } }; diff --git a/src/ui/Entry.cpp b/src/ui/Entry.cpp index fca5d67..36fb431 100644 --- a/src/ui/Entry.cpp +++ b/src/ui/Entry.cpp @@ -26,3 +26,13 @@ void Entry::moveCursorToEnd() { elm_entry_cursor_end_set(uniqueObj_.get()); } + +void Entry::setSingleline(bool singleline) +{ + elm_entry_single_line_set(uniqueObj_.get(), singleline ? EINA_TRUE : EINA_FALSE); +} + +bool Entry::isSingleline() +{ + return elm_entry_single_line_get(uniqueObj_.get()) != EINA_FALSE; +} diff --git a/src/ui/Entry.hpp b/src/ui/Entry.hpp index 744c6d2..2ae710a 100644 --- a/src/ui/Entry.hpp +++ b/src/ui/Entry.hpp @@ -12,6 +12,8 @@ class Entry : public Widget void setEntryText(const TranslatedString &text); std::string getEntryText(); void moveCursorToEnd(); + void setSingleline(bool singleline); + bool isSingleline(); protected: using Widget::Widget; diff --git a/src/ui/GenlistItem.cpp b/src/ui/GenlistItem.cpp index 56ee340..ae56774 100644 --- a/src/ui/GenlistItem.cpp +++ b/src/ui/GenlistItem.cpp @@ -362,6 +362,7 @@ Evas_Object *GenlistItem::realizeEntry(const std::string &part) auto entry = Widget::make(layout); layout->setPartContent("elm.swallow.content", entry); entry->setEntryText(entryText_); + entry->setSingleline(true); entry->setEvasSmartCallback("changed,user", [=]() { this->entryText_ = entry->getEntryText(); if (onContentValueChanged_) { diff --git a/src/view/LabelView.cpp b/src/view/LabelView.cpp new file mode 100644 index 0000000..d6fa2f7 --- /dev/null +++ b/src/view/LabelView.cpp @@ -0,0 +1,27 @@ +#include "LabelView.hpp" + +#include "AppContext.hpp" +#include "Button.hpp" +#include "NavigationContext.hpp" +#include "Singleton.hpp" + +#define EDJ_ACCESSORY "edje/accessibility-smart-switch-accessory.edj" +#define GRP_ACCESSORY "accessory" +#define PRT_ACCESSORY_LABEL "accessory_label" + +LabelView::LabelView(const NavigationContext &context, Presenter *presenter) + : NaviframeView(context), labelPresenter_(static_cast(presenter)) +{ + auto naviframe = context.getNaviframe(); + layout_ = Widget::make(naviframe, EDJ_ACCESSORY, GRP_ACCESSORY); + layout_->setText(PRT_ACCESSORY_LABEL, labelPresenter_->labelText_.value()); + + labelPresenter_->labelText_.attach([this](auto value) { + layout_->setText(PRT_ACCESSORY_LABEL, value); + }); + backItem_ = Widget::make