EditAlarmView: ask user before quit edition view. 88/101888/5
authorLukasz Stanislawski <l.stanislaws@samsung.com>
Fri, 2 Dec 2016 07:24:48 +0000 (08:24 +0100)
committerLukasz Stanislawski <l.stanislaws@samsung.com>
Wed, 14 Dec 2016 09:12:41 +0000 (01:12 -0800)
If user clicked back button in edit view, show popup to user
to confirm discarding changes.

Change-Id: Iedea0bb0cc7e93d5a836b0cf959725414a1dc9ce

clock/inc/Model/WeekFlags.h
clock/inc/Presenter/EditAlarmPresenter.h
clock/inc/Utils/Time.h
clock/inc/View/EditAlarmView.h
clock/res/po/en_US.po
clock/src/Presenter/EditAlarmPresenter.cpp
clock/src/Utils/Time.cpp
clock/src/View/EditAlarmView.cpp

index f03bf09..2f243fa 100644 (file)
@@ -50,7 +50,7 @@ namespace model {
                        bool Empty() const;
                        void Serialize(utils::IWriter &w) const;
                        int GetBitMask() const;
-                       inline bool operator==(const WeekFlags &a) { return a.raw_flags == raw_flags; }
+                       inline bool operator==(const WeekFlags &a) const { return a.raw_flags == raw_flags; }
                private:
                        int raw_flags;
        };
index bd3ff8f..93d948e 100644 (file)
@@ -30,6 +30,7 @@ namespace presenter {
                        model::Alarm *alarm_;
                        model::AlarmProvider *provider_;
                        view::EditAlarmView &view_;
+                       view::EditAlarmView::AlarmViewInfo info_;
                        void OnEditDone();
                        void OnEditCancel();
                        view::EditAlarmView::AlarmViewInfo GetDefaultInfo() const;
@@ -39,6 +40,8 @@ namespace presenter {
                        void UpdateAlarm(model::Alarm &alarm);
                        model::Alarm* GetMatchingAlarm(const std::string &name, const utils::Time &time);
                        void ShowAlarmUpdatedPopup(const utils::Time &time);
+                       void OnBackButton();
+                       void OnDiscardPopupOptionClicked(view::EditAlarmView::DiscardPopupOption option);
        };
 } /* presenter */
 
index 07524de..036de6c 100644 (file)
@@ -77,7 +77,7 @@ namespace utils {
                        /**
                         * @brief Compare operator
                         */
-                       bool operator==(const Time &a);
+                       bool operator==(const Time &a) const;
 
                        /**
                         * @brief Return year AD.
index 393b177..f133def 100644 (file)
@@ -45,12 +45,29 @@ namespace view {
                                Edit, /* Edit existing alarm mode */
                                Create, /* Create new alarm mode */
                        };
+                       enum class DiscardPopupOption {
+                               CANCEL,
+                               DISCARD
+                       };
                        typedef std::function<void(AlarmViewInfo)> EditDoneCallback;
                        typedef std::function<void(void)> EditCancelCallback;
+                       typedef std::function<void(void)> BackButtonCallback;
+                       typedef std::function<void(DiscardPopupOption)> DiscardPopupCallback;
 
                        void RegisterEditDoneCallback(EditDoneCallback cb) { onEditDone_ = cb; }
                        void RegisterEditCancelCallback(EditCancelCallback cb) { onEditCancel_ = cb; }
 
+                       /**
+                        * @brief Registers callback emitted when back button is clicked
+                        */
+                       void RegisterBackButtonCallback(BackButtonCallback cb) { onBackButton = cb; }
+
+                       /**
+                        * @brief Registers callback emitted when option has been chosen on
+                        * discard popup
+                        */
+                       void RegisterDiscardPopupCallback(DiscardPopupCallback cb) { onDiscardPopupCallback = cb; }
+
                        EditAlarmView(ui::IView &main);
 
                        ~EditAlarmView();
@@ -73,6 +90,22 @@ namespace view {
                         * @brief Shows toast popup window
                         */
                        void ShowPopup(const std::string &text);
+
+                       /**
+                        * @brief Shows discard popup
+                        */
+                       void ShowDiscardPopup();
+
+                       /**
+                        * @brief Hides discard popup
+                        */
+                       void HideDiscardPopup();
+
+                       /**
+                        * @brief Check if disard popup is visible
+                        */
+                       bool IsDiscardPopupVisible() const;
+
                protected:
                        virtual void CreateContent(Evas_Object *parent);
                        virtual void DestroyContent();
@@ -83,12 +116,15 @@ namespace view {
                        Evas_Object *right_btn_;
                        Evas_Object *main_radio_;
                        Evas_Object *icon_slider_;
+                       Evas_Object *discard_popup_;
 
                        /* child view of EditAlarmView */
                        WeekFlagsView week_flags_view_;
 
                        EditDoneCallback onEditDone_;
                        EditCancelCallback onEditCancel_;
+                       BackButtonCallback onBackButton;;
+                       DiscardPopupCallback onDiscardPopupCallback;
 
                        Elm_Object_Item *type_it_;
                        Elm_Object_Item *repeat_it_;
@@ -100,6 +136,7 @@ namespace view {
                        Mode mode_;
                        IView &main_;
 
+                       /* Efl callbacks */
                        static void OnCancelButtonClickedCb(void *data, Evas_Object *obj, void *event);
                        static void OnConfirmButtonClickedCb(void *data, Evas_Object *obj, void *event);
                        static void DateTimeChangedCallback(void *data, Evas_Object *obj, void *event);
@@ -107,13 +144,15 @@ namespace view {
                        static void CheckChangedCallback(void *data, Evas_Object *obj, void *event);
                        static void EntryChangedCallback(void *data, Evas_Object *obj, void *event);
                        static void KeyDownEventCallback(void *data, Evas *e, Evas_Object *obj, void *event);
-
                        static void RepeatItemSelectedCallback(void *data, Evas_Object *obj, void *event);
                        static void AlarmTypeItemSelectedCallback(void *data, Evas_Object *obj, void *event);
                        static void PopupListItemSelectedCallback(void *data, Evas_Object *obj, void *event);
                        static void PopupHide(void *data, Evas_Object *obj, void *event);
                        static void SnoozeItemSelectedCallback(void *data, Evas_Object *obj, void *event);
                        static void ChooseAlarmToneItemSelectedCallback(void *data, Evas_Object *obj, void *event);
+                       static void BackButtonOnMainClicked(void *data, Evas_Object *obj, void *event);
+                       static void PopupCancelButtonClicked(void *data, Evas_Object *obj, void *event_info);
+                       static void PopupDiscardButtonClicked(void *data, Evas_Object *obj, void *event_info);
 
                        void CreateGenlistItems();
                        void ShowSetTypePopup();
index 5f15c24..34b560d 100644 (file)
@@ -175,3 +175,12 @@ msgstr "Create"
 
 msgid "IDS_CLOCK_TPOP_ALARM_ALREADY_SET_FOR_PS_EXISTING_ALARM_UPDATED"
 msgstr "Alarm already set for %s. Existing alarm updated."
+
+msgid "IDS_CLOCK_BUTTON_DISCARD_ABB3"
+msgstr "Discard"
+
+msgid "IDS_CLOCK_HEADER_DISCARD_CHANGES_ABB"
+msgstr "Discard change"
+
+msgid "IDS_CLOCK_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "All changes will be discarded."
index 97276e3..d86b045 100644 (file)
@@ -27,13 +27,18 @@ using namespace presenter;
 using namespace view;
 using namespace model;
 using namespace utils;
+using std::placeholders::_1;
+
+const double time_truncate_factor = 60 * 1000; // 60 seconds
 
 EditAlarmPresenter::EditAlarmPresenter(model::AlarmProvider *provider, model::Alarm *alarm, view::EditAlarmView& view) :
        provider_(provider), view_(view), alarm_(alarm)
 {
        view_.RegisterEditDoneCallback(std::bind(&EditAlarmPresenter::OnEditDone, this));
        view_.RegisterEditCancelCallback(std::bind(&EditAlarmPresenter::OnEditCancel, this));
-       view_.SetData(GetInfoForAlarm(alarm));
+       view_.RegisterBackButtonCallback(std::bind(&EditAlarmPresenter::OnBackButton, this));
+       info_ = GetInfoForAlarm(alarm);
+       view_.SetData(info_);
        view_.SetMode(alarm == nullptr ? EditAlarmView::Mode::Create : EditAlarmView::Mode::Edit);
        view_.PushPage();
 }
@@ -78,11 +83,11 @@ view::EditAlarmView::AlarmViewInfo EditAlarmPresenter::GetInfoForAlarm(const Ala
 Alarm* EditAlarmPresenter::GetMatchingAlarm(const std::string &name, const Time &time)
 {
        auto alarms = provider_->GetAlarms();
-       double truncate_factor = 60 * 1000; // 60 seconds
-       auto truncated_time = time.Truncate(truncate_factor);
+       auto truncated_time = time.Truncate(time_truncate_factor);
 
-       for (auto &alarm : alarms) {
-               if ((alarm.get().GetTime().Truncate(truncate_factor) == truncated_time) &&
+       for (auto &alarm : alarms)
+       {
+               if ((alarm.get().GetTime().Truncate(time_truncate_factor) == truncated_time) &&
                        (alarm.get().GetName() == view_.GetData().name))
                        return &alarm.get();
        }
@@ -181,3 +186,44 @@ void EditAlarmPresenter::OnEditCancel()
 {
        view_.PopPage();
 }
+
+void EditAlarmPresenter::OnDiscardPopupOptionClicked(EditAlarmView::DiscardPopupOption option)
+{
+       view_.RegisterDiscardPopupCallback(nullptr);
+
+       switch (option)
+       {
+               case EditAlarmView::DiscardPopupOption::CANCEL:
+                       view_.HideDiscardPopup();
+                       break;
+               case EditAlarmView::DiscardPopupOption::DISCARD:
+                       view_.HideDiscardPopup();
+                       view_.PopPage();
+                       break;
+       }
+}
+
+static bool CompareAlarmInfoStructures(const EditAlarmView::AlarmViewInfo &info1, const EditAlarmView::AlarmViewInfo &info2)
+{
+       return info1.name == info2.name &&
+               info1.time.Truncate(time_truncate_factor) == info2.time.Truncate(time_truncate_factor) &&
+               info1.flags == info2.flags &&
+               info1.volume == info2.volume &&
+               info1.snooze == info2.snooze &&
+               info1.melody == info2.melody &&
+               info1.type == info2.type;
+}
+
+void EditAlarmPresenter::OnBackButton()
+{
+       if (view_.IsDiscardPopupVisible())
+               return;
+
+       if (!CompareAlarmInfoStructures(info_, view_.GetData()))
+       {
+               view_.RegisterDiscardPopupCallback(std::bind(&EditAlarmPresenter::OnDiscardPopupOptionClicked, this, _1));
+               view_.ShowDiscardPopup();
+       } else {
+               view_.PopPage();
+       }
+}
index 316d34c..fa5af36 100644 (file)
@@ -272,7 +272,7 @@ Time::Time(unsigned int year, Month month, unsigned int day,
        i18n_ucalendar_destroy(calendar);
 }
 
-bool Time::operator==(const Time &a)
+bool Time::operator==(const Time &a) const
 {
        return a.milliseconds_ == milliseconds_;
 }
index 35c8bae..9770a34 100644 (file)
@@ -182,6 +182,12 @@ const char *EditAlarmView::GetTitle()
        return NULL;
 }
 
+void EditAlarmView::BackButtonOnMainClicked(void *data, Evas_Object *obj, void *event)
+{
+       EditAlarmView *view = static_cast<EditAlarmView*>(data);
+       if (view->onBackButton) view->onBackButton();
+}
+
 void EditAlarmView::CreateContent(Evas_Object *parent)
 {
        // set page style - "basic" style is supported by default tizen theme
@@ -208,6 +214,8 @@ void EditAlarmView::CreateContent(Evas_Object *parent)
        elm_genlist_mode_set(content_, ELM_LIST_COMPRESS);
        elm_genlist_realization_mode_set(content_, EINA_TRUE);
        evas_object_show(content_);
+       eext_object_event_callback_add(content_, EEXT_CALLBACK_BACK,
+                       EditAlarmView::BackButtonOnMainClicked, this);
 
        // fill created parts in object item
        elm_object_item_translatable_part_text_set(navi_item_, "elm.text.title",
@@ -582,3 +590,52 @@ void EditAlarmView::ShowPopup(const std::string &text)
 {
        PopupManager::CreatePopup(main_, text);
 }
+
+void EditAlarmView::PopupDiscardButtonClicked(void *data, Evas_Object *obj, void *event_info)
+{
+       EditAlarmView *view = static_cast<EditAlarmView*>(data);
+       if (view->onDiscardPopupCallback) view->onDiscardPopupCallback(DiscardPopupOption::DISCARD);
+}
+
+void EditAlarmView::PopupCancelButtonClicked(void *data, Evas_Object *obj, void *event_info)
+{
+       EditAlarmView *view = static_cast<EditAlarmView*>(data);
+       if (view->onDiscardPopupCallback) view->onDiscardPopupCallback(DiscardPopupOption::CANCEL);
+}
+
+void EditAlarmView::ShowDiscardPopup()
+{
+       if (discard_popup_)
+               return;
+
+       discard_popup_ = elm_popup_add(elm_object_top_widget_get(content_));
+       elm_popup_align_set(discard_popup_, ELM_NOTIFY_ALIGN_FILL, 1.0);
+       elm_object_translatable_part_text_set(discard_popup_, "title,text", "IDS_CLOCK_HEADER_DISCARD_CHANGES_ABB");
+       elm_object_translatable_text_set(discard_popup_, "IDS_CLOCK_POP_ALL_CHANGES_WILL_BE_DISCARDED");
+
+       Evas_Object *btn = elm_button_add(discard_popup_);
+       elm_object_translatable_text_set(btn, "IDS_COM_POP_CANCEL");
+       evas_object_smart_callback_add(btn, "clicked", EditAlarmView::PopupCancelButtonClicked, this);
+       elm_object_part_content_set(discard_popup_, "button1", btn);
+       evas_object_show(btn);
+
+       btn = elm_button_add(discard_popup_);
+       elm_object_translatable_text_set(btn, "IDS_CLOCK_BUTTON_DISCARD_ABB3");
+       evas_object_smart_callback_add(btn, "clicked", EditAlarmView::PopupDiscardButtonClicked, this);
+       elm_object_part_content_set(discard_popup_, "button2", btn);
+       evas_object_show(btn);
+
+       evas_object_show(discard_popup_);
+}
+
+void EditAlarmView::HideDiscardPopup()
+{
+       if (discard_popup_)
+               evas_object_del(discard_popup_);
+       discard_popup_ = nullptr;
+}
+
+bool EditAlarmView::IsDiscardPopupVisible() const
+{
+       return discard_popup_ != nullptr;
+}