From: Kamil Lipiszko Date: Thu, 24 Aug 2017 08:18:10 +0000 (+0200) Subject: [EditAlarmView] Update date on user time change X-Git-Tag: submit/tizen/20170825.140154^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F44%2F145944%2F10;p=profile%2Fmobile%2Fapps%2Fnative%2Fclock.git [EditAlarmView] Update date on user time change 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 --- diff --git a/clock/inc/Utils/Time.h b/clock/inc/Utils/Time.h index b0a1be8..5e36760 100644 --- a/clock/inc/Utils/Time.h +++ b/clock/inc/Utils/Time.h @@ -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); diff --git a/clock/inc/View/EditAlarmView.h b/clock/inc/View/EditAlarmView.h index fec4486..1f7155c 100644 --- a/clock/inc/View/EditAlarmView.h +++ b/clock/inc/View/EditAlarmView.h @@ -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(); diff --git a/clock/res/edje/edit_alarm.edc b/clock/res/edje/edit_alarm.edc index ccbf303..c56ea80 100644 --- a/clock/res/edje/edit_alarm.edc +++ b/clock/res/edje/edit_alarm.edc @@ -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; diff --git a/clock/src/Presenter/EditAlarmPresenter.cpp b/clock/src/Presenter/EditAlarmPresenter.cpp index ede7d9a..e404f57 100644 --- a/clock/src/Presenter/EditAlarmPresenter.cpp +++ b/clock/src/Presenter/EditAlarmPresenter.cpp @@ -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); diff --git a/clock/src/Utils/SystemSettings.cpp b/clock/src/Utils/SystemSettings.cpp index 5a29af1..1e2bce3 100644 --- a/clock/src/Utils/SystemSettings.cpp +++ b/clock/src/Utils/SystemSettings.cpp @@ -75,7 +75,6 @@ bool SystemSettings::Register() return is_registered; } - void SystemSettings::OnLanguageChanged(system_settings_key_e key, void *user_data) { free(locale_); diff --git a/clock/src/Utils/Time.cpp b/clock/src/Utils/Time.cpp index fde19ee..09e07f6 100644 --- a/clock/src/Utils/Time.cpp +++ b/clock/src/Utils/Time.cpp @@ -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 diff --git a/clock/src/View/EditAlarmView.cpp b/clock/src/View/EditAlarmView.cpp index 6527a8d..e383e4f 100644 --- a/clock/src/View/EditAlarmView.cpp +++ b/clock/src/View/EditAlarmView.cpp @@ -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(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(data); - if (!strcmp(part, "elm.swallow.timepicker")) { - EditAlarmView *view = static_cast(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(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(user_data); + if (view) { + view->UpdateTime(view->data_.time); + view->UpdateView(); + } + + return ECORE_CALLBACK_RENEW; +} + void EditAlarmView::SetData(const AlarmViewInfo &info) { data_ = info;