[EditAlarmView] Update date on user time change 44/145944/10 submit/tizen/20170825.140154 submit/tizen/20170912.085229
authorKamil Lipiszko <k.lipiszko@samsung.com>
Thu, 24 Aug 2017 08:18:10 +0000 (10:18 +0200)
committerKamil Lipiszko <k.lipiszko@samsung.com>
Fri, 25 Aug 2017 12:51:53 +0000 (14:51 +0200)
This patch validates time set in datetime widget. If set time already
passed and date is not valid anymore, it changes to the nearest upcoming
hour.

Change-Id: Ic02e64f6303426b85c651173a3103618e476c6ea

clock/inc/Utils/Time.h
clock/inc/View/EditAlarmView.h
clock/res/edje/edit_alarm.edc
clock/src/Presenter/EditAlarmPresenter.cpp
clock/src/Utils/SystemSettings.cpp
clock/src/Utils/Time.cpp
clock/src/View/EditAlarmView.cpp

index b0a1be8e2731fa51f0eef311adb41d09d45b4ca1..5e36760a0b8e5f65cae83c4c6d5ca52e6fd097d7 100644 (file)
@@ -95,6 +95,31 @@ namespace utils {
                         */
                        bool operator==(const Time &a) const;
 
+                       /**
+                        * @brief Not equal to operator
+                        */
+                       bool operator!=(const Time &a) const;
+
+                       /**
+                        * @brief Greater than operator
+                        */
+                       bool operator>(const Time &a) const;
+
+                       /**
+                        * @brief Less than operator
+                        */
+                       bool operator<(const Time &a) const;
+
+                       /**
+                        * @brief Greater than or equal to operator
+                        */
+                       bool operator>=(const Time &a) const;
+
+                       /**
+                        * @brief Less than or equal to operator
+                        */
+                       bool operator<=(const Time &a) const;
+
                        /**
                         * @brief Return year AD.
                         */
@@ -168,16 +193,6 @@ namespace utils {
                         */
                        static int DateCompare(const Time &end, const Time &start);
 
-                       /**
-                        * Return difference between hours in seconds
-                        *
-                        * @param end End of the time
-                        * @param start Start of the time
-                        *
-                        * @return Number of seconds
-                        */
-                       static int TimeCompare(const Time &end, const Time &start);
-
                        /**
                         * @brief Returns Time adjusted to localtime.
                         */
@@ -255,7 +270,7 @@ namespace utils {
                         *
                         * @return Difference between times in seconds
                         */
-                       static int Difftime(const Time &end, const Time &start);
+                       static double Difftime(const Time &end, const Time &start);
 
                private:
                        Time(double milliseconds, const std::string &tz);
index fec448678b7a7649e3ee42986b347985fd5b77dd..1f7155c8a7eb470a5b2cf03fb7a29b11c57b6b71 100644 (file)
@@ -195,11 +195,14 @@ namespace view {
                        WeekFlagsView week_flags_view_;
 
                        Elm_Object_Item *date_it_;
+                       Elm_Object_Item *time_it_;
                        Elm_Object_Item *type_it_;
                        Elm_Object_Item *repeat_it_;
                        Elm_Object_Item *volume_it_;
                        Elm_Object_Item *tone_it_;
 
+                       Ecore_Timer *timer_ = nullptr;
+
                        AlarmViewInfo data_;
                        bool is_muted_;
                        Mode mode_;
@@ -228,6 +231,7 @@ namespace view {
                        static void PopupDatePickerCancelClicked(void *data, Evas_Object *obj, void *event_info);
                        static void PopupDatePickerSetClicked(void *data, Evas_Object *obj, void *event_info);
                        static void PopupDatePickerDateChanged(void *data, Evas_Object *obj, void *event_info);
+                       static Eina_Bool TimerCb(void *user_data);
 
                        void CreateGenlistItems();
                        void ShowSetTypePopup();
index ccbf3036d4574129fad4cb64b276a33d2026d77c..c56ea80a026d45aa9d8e14d868a7ca00102176e5 100644 (file)
@@ -196,9 +196,9 @@ collections {
                        }
                }
        }
-       group { name: "elm/genlist/item/alarm:timepicker/default";
+       group { name: "elm/genlist/item/alarm:datepicker/default";
                data.item: "texts" "elm.text.date";
-               data.item: "contents" "elm.swallow.btn elm.swallow.timepicker";
+               data.item: "contents" "elm.swallow.btn";
                data.item: "banded_bg_area" "elm.swallow.bg";
                styles {
                        style {
@@ -209,7 +209,7 @@ collections {
                parts {
                        spacer { "base"; scale;
                                desc {
-                                       min: 0 474;
+                                       min: 0 111;
                                }
                        }
                        swallow { "elm.swallow.bg"; scale;
@@ -218,24 +218,10 @@ collections {
                                        rel2.to: "base";
                                }
                        }
-                       swallow { "elm.swallow.timepicker"; scale;
-                               desc {
-                                       min: 0 392;
-                                       max: -1 392;
-                                       fixed: 0 1;
-                                       align: 0.5 1.0;
-                                       rel1 {
-                                               relative: 0.0 1.0;
-                                               to_x: "base";
-                                               to_y: "pd.date.timepicker";
-                                       }
-                                       rel2.to: "base";
-                               }
-                       }
                        spacer { "pd.top"; scale;
                                desc {
-                                       min: 0 32;
-                                       max: -1 32;
+                                       min: 0 44;
+                                       max: -1 44;
                                        align: 0.5 0.0;
                                        fixed: 0 1;
                                }
@@ -271,18 +257,6 @@ collections {
                                        }
                                }
                        }
-                       spacer { "pd.date.timepicker"; scale;
-                               desc {
-                                       min: 0 32;
-                                       max: -1 32;
-                                       fixed: 0 1;
-                                       align: 0.5 0.0;
-                                       rel1 {
-                                               relative: 0.0 1.0;
-                                               to_y: "elm.text.date";
-                                       }
-                               }
-                       }
                        textblock { "elm.text.date"; scale;
                                desc {
                                        min: 408 45;
index ede7d9af457c1666f9a2c9788386c90a57599a69..e404f57b10df4e5b61743daa25f5f6365da6c373 100644 (file)
@@ -121,7 +121,7 @@ void EditAlarmPresenter::UpdateAlarm(AlarmList::Iterator it)
 
        SetAlarmProperties(alarm, view_.GetData());
 
-       if (alarm.GetWeekFlags().Empty() && Time::Difftime(alarm.GetTime(), Time::Now()) <= 0)
+       if (alarm.GetWeekFlags().Empty() && alarm.GetTime() < Time::Now())
                alarm.Deactivate();
 
        model_.Replace(it, alarm);
@@ -140,7 +140,7 @@ void EditAlarmPresenter::CreateNewAlarm()
 
        SetAlarmProperties(new_alarm, view_.GetData());
 
-       if (!new_alarm.GetWeekFlags().Empty() || Time::Difftime(new_alarm.GetTime(), Time::Now()) > 0)
+       if (!new_alarm.GetWeekFlags().Empty() || new_alarm.GetTime() > Time::Now())
                new_alarm.Activate();
 
        model_.Add(new_alarm);
index 5a29af123b50aa1874915c1757928853f7f0b5fb..1e2bce3cb59a6493ad8e2a601b51694cf79bc356 100644 (file)
@@ -75,7 +75,6 @@ bool SystemSettings::Register()
        return is_registered;
 }
 
-
 void SystemSettings::OnLanguageChanged(system_settings_key_e key, void *user_data)
 {
        free(locale_);
index fde19eef37d3a5b4083d666ab4c5eb7559644add..09e07f615c67f78c7093da56781016860fc305d5 100644 (file)
@@ -289,44 +289,59 @@ bool Time::operator==(const Time &a) const
        return floor(a.milliseconds_) == floor(milliseconds_);
 }
 
-static int difftime(std::tm start, std::tm end)
+bool Time::operator>(const Time &a) const
 {
-       time_t endTime = mktime(&end);
-       time_t startTime = mktime(&start);
-
-       if (endTime == (time_t)(-1) || startTime == (time_t)(-1)) {
-               return INT_MAX;
-       }
+       return floor(milliseconds_) > floor(a.milliseconds_);
+}
 
-       return (int)(difftime(endTime, startTime));
+bool Time::operator<(const Time &a) const
+{
+       return floor(milliseconds_) < floor(a.milliseconds_);
 }
 
-int Time::Difftime(const Time &end, const Time &start)
+bool Time::operator>=(const Time &a) const
 {
-       return (int)difftime(start.GetTmStruct(), end.GetTmStruct());
+       return floor(milliseconds_) >= floor(a.milliseconds_);
 }
 
-int Time::DateCompare(const Time &end, const Time &start)
+bool Time::operator<=(const Time &a) const
 {
-       tm endTm = end.GetTmStruct();
-       endTm.tm_sec = 0;
-       endTm.tm_min = 0;
-       endTm.tm_hour = 0;
+       return floor(milliseconds_) <= floor(a.milliseconds_);
+}
 
-       tm startTm = start.GetTmStruct();
-       startTm.tm_sec = 0;
-       startTm.tm_min = 0;
-       startTm.tm_hour = 0;
+bool Time::operator!=(const Time &a) const
+{
+       return floor(milliseconds_) != floor(a.milliseconds_);
+}
 
-       return (difftime(startTm, endTm) / SECONDS_PER_DAY);
+double Time::Difftime(const Time &end, const Time &start)
+{
+       return floor(end.milliseconds_) - floor(start.milliseconds_);
 }
 
-int Time::TimeCompare(const Time &end, const Time &start)
+int Time::DateCompare(const Time &end, const Time &start)
 {
-       tm endTm = end.GetTmStruct();
-       tm startTm = start.GetTmStruct();
+       auto endDate = Time(
+               end.GetYear(),
+               end.GetMonth(),
+               end.GetDay(),
+               0,
+               0,
+               0,
+               0
+       );
+
+       auto startDate = Time(
+               start.GetYear(),
+               start.GetMonth(),
+               start.GetDay(),
+               0,
+               0,
+               0,
+               0
+       );
 
-       return (difftime(startTm, endTm) % SECONDS_PER_DAY);
+       return (round(Difftime(endDate, startDate) / 1000) / SECONDS_PER_DAY);
 }
 
 Time Time::Now(void)
@@ -504,29 +519,28 @@ Time::Month Time::Int2Month(int month)
 Time Time::GetUpcoming(const Time &time)
 {
        Time now = Now();
-       int daysLeft = DateCompare(time, now);
-       int secondsLeft = Time::TimeCompare(time, now);
-
-       int x = 0;
-
-       if (daysLeft == 0 && secondsLeft <= 0)
-               x = 1;
-       else if (daysLeft < 0) {
-               if (secondsLeft > 0)
-                       x = daysLeft*(-1);
-               else
-                       x = daysLeft*(-1) + 1;
-       }
 
-       return Time(
-               time.GetYear(),
-               time.GetMonth(),
-               time.GetDay() + x,
+       auto up = Time(
+               now.GetYear(),
+               now.GetMonth(),
+               now.GetDay(),
                time.GetHour(),
                time.GetMinute(),
                0,
-               0
-       );
+               0);
+
+       if (up < now)
+               return Time(
+                       now.GetYear(),
+                       now.GetMonth(),
+                       now.GetDay() + 1,
+                       time.GetHour(),
+                       time.GetMinute(),
+                       0,
+                       0
+                       );
+
+       return up;
 }
 
 std::tm Time::GetTmStruct() const
index 6527a8dc196baa1fed43ccd2c06f2a1e5ac10352..e383e4f6f29e720774dc0cdf566b27b52f39e05d 100644 (file)
@@ -212,6 +212,9 @@ void EditAlarmView::CreateContent(Evas_Object *parent)
                                "edje/edit_alarm.edj"));
 
        CreateGenlistItems();
+
+       if (!timer_)
+               timer_ = ecore_timer_add(1.0, TimerCb, this);
 }
 
 void EditAlarmView::DateTimeChangedCallback(void *data, Evas_Object *obj, void *event)
@@ -220,7 +223,20 @@ void EditAlarmView::DateTimeChangedCallback(void *data, Evas_Object *obj, void *
        Elm_Datetime_Time edt;
 
        if (elm_datetime_value_get(obj, &edt)) {
-               view->data_.time = ConvertElmDatetimeTimeToTime(edt);
+
+               auto time = ConvertElmDatetimeTimeToTime(edt);
+               view->data_.time = Time(
+                       view->data_.time.GetYear(),
+                       view->data_.time.GetMonth(),
+                       view->data_.time.GetDay(),
+                       time.GetHour(),
+                       time.GetMinute(),
+                       0,
+                       0
+                       );
+
+               view->data_.time = Time::GetUpcoming(view->data_.time);
+               view->UpdateView();
        } else {
                ERR("elm_datetime_value_get failed");
        }
@@ -357,6 +373,8 @@ void EditAlarmView::PopupDatePickerDateChanged(void *data, Evas_Object *obj, voi
        int daysLeft = Time::DateCompare(calendarTime, Time::Now());
 
        Evas_Object *setButton = elm_object_part_content_get(view->datepicker_popup_, "button2");
+       if (!setButton)
+               return;
 
        if (daysLeft < 0)
                elm_object_disabled_set(setButton, EINA_TRUE);
@@ -423,11 +441,14 @@ void EditAlarmView::PopupDatePickerSetClicked(void *data, Evas_Object *obj, void
 void EditAlarmView::UpdateTime(Time time)
 {
        if (data_.flags.Empty()) {
-               data_.time = Time::GetUpcoming(time);
-
-               if (time.GetDay() != data_.time.GetDay())
+               if (time > Time::Now())
+                       data_.time = time;
+               else {
+                       data_.time = Time::GetUpcoming(time);
                        PopupManager::CreatePopup(*this,
                                        "Can't set alarms for time in past. Tomorrow's date set.", 3.0);
+               }
+
        } else {
                Time now = Time::Now();
                data_.time = Time(
@@ -440,7 +461,6 @@ void EditAlarmView::UpdateTime(Time time)
                        0
                        );
        }
-
 }
 
 void EditAlarmView::ShowDatePickerPopup() {
@@ -521,10 +541,11 @@ void EditAlarmView::CreateGenlistItems()
 
        // time chooser
        itc = elm_genlist_item_class_new();
-       itc->item_style = "alarm:timepicker";
+       itc->item_style = "alarm:datepicker";
        itc->func.text_get = [](void *data, Evas_Object *o, const char *part) -> char * {
                EditAlarmView *view = static_cast<EditAlarmView*>(data);
                if (!strcmp(part, "elm.text.date")) {
+
                        if (view->data_.flags.Empty())
                                return strdup(view->GetDate().c_str());
                        else
@@ -536,23 +557,7 @@ void EditAlarmView::CreateGenlistItems()
        itc->func.content_get = [](void *data, Evas_Object *o, const char *part) -> Evas_Object* {
                EditAlarmView *view = static_cast<EditAlarmView*>(data);
 
-               if (!strcmp(part, "elm.swallow.timepicker")) {
-                       EditAlarmView *view = static_cast<EditAlarmView*>(data);
-                       Evas_Object *dt = elm_datetime_add(o);
-                       elm_datetime_format_set(dt, SystemSettings::Is24HourFormatPrefered() ? "%k %M" : "%l %M %p");
-                       elm_object_style_set(dt, "time_layout"); // from tizen-theme
-                       evas_object_smart_callback_add(dt, "changed"
-                                       , EditAlarmView::DateTimeChangedCallback, view);
-                       auto elm_time = view->data_.time.GetTmStruct();
-                       elm_datetime_value_set(dt, &elm_time);
-                       evas_object_show(dt);
-
-                       return dt;
-               } else if (!strcmp(part, "elm.swallow.btn")) {
-
-
-                       ThemeExtension::AddTheme(TizenAppUtils::GetResourcePath(TizenAppUtils::APP_DIR_RESOURCE,
-                                               "edje/edit_alarm.edj"));
+               if (!strcmp(part, "elm.swallow.btn")) {
 
                        Evas_Object *btn = elm_button_add(o);
 
@@ -576,6 +581,32 @@ void EditAlarmView::CreateGenlistItems()
        elm_genlist_item_select_mode_set(date_it_, ELM_OBJECT_SELECT_MODE_NONE);
        elm_genlist_item_class_unref(itc);
 
+       itc = elm_genlist_item_class_new();
+       itc->item_style = "full";
+       itc->func.text_get = nullptr;
+       itc->func.content_get = [](void *data, Evas_Object *o, const char *part) -> Evas_Object* {
+
+               EditAlarmView *view = static_cast<EditAlarmView*>(data);
+
+               Evas_Object *dt = elm_datetime_add(o);
+               elm_datetime_format_set(dt,
+                               SystemSettings::Is24HourFormatPrefered() ? "%k %M" : "%l %M %p");
+               elm_object_style_set(dt, "time_layout"); // from tizen-theme
+               evas_object_smart_callback_add(dt, "changed"
+                               , EditAlarmView::DateTimeChangedCallback, view);
+
+               auto elm_time = view->data_.time.GetTmStruct();
+               elm_datetime_value_set(dt, &elm_time);
+
+               evas_object_show(dt);
+
+               return dt;
+       };
+
+       time_it_ = elm_genlist_item_append(content_, itc, this, NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
+       elm_genlist_item_select_mode_set(time_it_, ELM_OBJECT_SELECT_MODE_NONE);
+       elm_genlist_item_class_unref(itc);
+
        // repeat flags chooser
        itc = elm_genlist_item_class_new();
        itc->item_style = "double_label"; // from tizen-theme
@@ -729,6 +760,11 @@ void EditAlarmView::DestroyContent()
        content_ = nullptr;
        evas_object_del(left_btn_);
        evas_object_del(right_btn_);
+
+       if (timer_) {
+               ecore_timer_del(timer_);
+               timer_ = nullptr;
+       }
 }
 
 void EditAlarmView::PopupListItemSelectedCallback(void *data, Evas_Object *obj, void *event)
@@ -824,6 +860,17 @@ void EditAlarmView::OnWeekFlagsPagePopped(void)
        UpdateView();
 }
 
+Eina_Bool EditAlarmView::TimerCb(void *user_data)
+{
+       EditAlarmView *view = static_cast<EditAlarmView *>(user_data);
+       if (view) {
+               view->UpdateTime(view->data_.time);
+               view->UpdateView();
+       }
+
+       return ECORE_CALLBACK_RENEW;
+}
+
 void EditAlarmView::SetData(const AlarmViewInfo &info)
 {
        data_ = info;