From 57b8cf4f19a013533c6c64f59c9c7838a7976a72 Mon Sep 17 00:00:00 2001 From: Gitsaibot Date: Sun, 10 Nov 2019 18:43:26 +0100 Subject: [PATCH 01/95] Remove static member accessed via instance reference --- src/com/android/calendar/DayView.java | 29 +++++++-------- .../calendar/agenda/AgendaAdapter.java | 9 ++--- .../calendar/agenda/AgendaByDayAdapter.java | 9 ++--- .../calendar/month/MonthByWeekFragment.java | 2 +- .../calendar/month/MonthWeekEventsView.java | 37 +++++++++---------- .../month/SimpleDayPickerFragment.java | 7 ++-- .../calendar/month/SimpleWeekView.java | 15 ++++---- .../SelectCalendarsSimpleAdapter.java | 9 ++--- 8 files changed, 55 insertions(+), 62 deletions(-) diff --git a/src/com/android/calendar/DayView.java b/src/com/android/calendar/DayView.java index 2ebcb929f..a00fb9d32 100644 --- a/src/com/android/calendar/DayView.java +++ b/src/com/android/calendar/DayView.java @@ -808,21 +808,20 @@ public class DayView extends View implements View.OnCreateContextMenuListener, mCurrentTime.set(currentTime); mTodayJulianDay = Time.getJulianDay(currentTime, mCurrentTime.gmtoff); - DynamicTheme dynTheme = new DynamicTheme(); - mWeek_todayColor = dynTheme.getColor(mContext, "week_today"); - mWeek_saturdayColor = dynTheme.getColor(mContext, "week_saturday"); - mWeek_sundayColor = dynTheme.getColor(mContext, "week_sunday"); - mCalendarDateBannerTextColor = dynTheme.getColor(mContext, "calendar_date_banner_text_color"); - mFutureBgColorRes = dynTheme.getColor(mContext, "calendar_future_bg_color"); - mBgColor = dynTheme.getColor(mContext, "calendar_hour_background"); - mCalendarHourLabelColor = dynTheme.getColor(mContext, "calendar_hour_label"); - mCalendarGridAreaSelected = dynTheme.getColor(mContext, "calendar_grid_area_selected"); - mCalendarGridLineInnerHorizontalColor = dynTheme.getColor(mContext, "calendar_grid_line_inner_horizontal_color"); - mCalendarGridLineInnerVerticalColor = dynTheme.getColor(mContext, "calendar_grid_line_inner_vertical_color"); - mPressedColor = dynTheme.getColor(mContext, "pressed"); - mClickedColor = dynTheme.getColor(mContext, "day_event_clicked_background_color"); - mEventTextColor = dynTheme.getColor(mContext, "calendar_event_text_color"); - mMoreEventsTextColor = dynTheme.getColor(mContext, "month_event_other_color"); + mWeek_todayColor = DynamicTheme.getColor(mContext, "week_today"); + mWeek_saturdayColor = DynamicTheme.getColor(mContext, "week_saturday"); + mWeek_sundayColor = DynamicTheme.getColor(mContext, "week_sunday"); + mCalendarDateBannerTextColor = DynamicTheme.getColor(mContext, "calendar_date_banner_text_color"); + mFutureBgColorRes = DynamicTheme.getColor(mContext, "calendar_future_bg_color"); + mBgColor = DynamicTheme.getColor(mContext, "calendar_hour_background"); + mCalendarHourLabelColor = DynamicTheme.getColor(mContext, "calendar_hour_label"); + mCalendarGridAreaSelected = DynamicTheme.getColor(mContext, "calendar_grid_area_selected"); + mCalendarGridLineInnerHorizontalColor = DynamicTheme.getColor(mContext, "calendar_grid_line_inner_horizontal_color"); + mCalendarGridLineInnerVerticalColor = DynamicTheme.getColor(mContext, "calendar_grid_line_inner_vertical_color"); + mPressedColor = DynamicTheme.getColor(mContext, "pressed"); + mClickedColor = DynamicTheme.getColor(mContext, "day_event_clicked_background_color"); + mEventTextColor = DynamicTheme.getColor(mContext, "calendar_event_text_color"); + mMoreEventsTextColor = DynamicTheme.getColor(mContext, "month_event_other_color"); int gridLineColor = mResources.getColor(R.color.calendar_grid_line_highlight_color); Paint p = mSelectionPaint; diff --git a/src/com/android/calendar/agenda/AgendaAdapter.java b/src/com/android/calendar/agenda/AgendaAdapter.java index 1c13e166c..db28b7e21 100644 --- a/src/com/android/calendar/agenda/AgendaAdapter.java +++ b/src/com/android/calendar/agenda/AgendaAdapter.java @@ -63,13 +63,12 @@ public class AgendaAdapter extends ResourceCursorAdapter { public AgendaAdapter(Context context, int resource) { super(context, resource, null); - DynamicTheme theme = new DynamicTheme(); mResources = context.getResources(); mNoTitleLabel = mResources.getString(R.string.no_title_label); - mDeclinedColor = theme.getColor(context, "agenda_item_declined_color"); - mStandardColor = theme.getColor(context, "agenda_item_standard_color"); - mWhereDeclinedColor = theme.getColor(context, "agenda_item_where_declined_text_color"); - mWhereColor = theme.getColor(context, "agenda_item_where_text_color"); + mDeclinedColor = DynamicTheme.getColor(context, "agenda_item_declined_color"); + mStandardColor = DynamicTheme.getColor(context, "agenda_item_standard_color"); + mWhereDeclinedColor = DynamicTheme.getColor(context, "agenda_item_where_declined_text_color"); + mWhereColor = DynamicTheme.getColor(context, "agenda_item_where_text_color"); mStringBuilder = new StringBuilder(50); mFormatter = new Formatter(mStringBuilder, Locale.getDefault()); diff --git a/src/com/android/calendar/agenda/AgendaByDayAdapter.java b/src/com/android/calendar/agenda/AgendaByDayAdapter.java index b4a2adeb0..52f787d54 100644 --- a/src/com/android/calendar/agenda/AgendaByDayAdapter.java +++ b/src/com/android/calendar/agenda/AgendaByDayAdapter.java @@ -172,7 +172,6 @@ public class AgendaByDayAdapter extends BaseAdapter { return mAgendaAdapter.getView(position, convertView, parent); } - DynamicTheme theme = new DynamicTheme(); RowInfo row = mRowInfo.get(position); if (row.mType == TYPE_DAY) { ViewHolder holder = null; @@ -238,10 +237,10 @@ public class AgendaByDayAdapter extends BaseAdapter { // Set the background of the view, it is grayed for day that are in the past and today if (row.mDay > mTodayJulianDay) { - agendaDayView.setBackgroundResource(theme.getDrawableId(mContext, "agenda_item_bg_primary")); + agendaDayView.setBackgroundResource(DynamicTheme.getDrawableId(mContext, "agenda_item_bg_primary")); holder.grayed = false; } else { - agendaDayView.setBackgroundResource(theme.getDrawableId(mContext, "agenda_item_bg_secondary")); + agendaDayView.setBackgroundResource(DynamicTheme.getDrawableId(mContext, "agenda_item_bg_secondary")); holder.grayed = true; } return agendaDayView; @@ -263,11 +262,11 @@ public class AgendaByDayAdapter extends BaseAdapter { // if event in the past or started already, un-bold the title and set the background if ((!allDay && row.mEventStartTimeMilli <= System.currentTimeMillis()) || (allDay && row.mDay <= mTodayJulianDay)) { - itemView.setBackgroundResource(theme.getDrawableId(mContext, "agenda_item_bg_secondary")); + itemView.setBackgroundResource(DynamicTheme.getDrawableId(mContext, "agenda_item_bg_secondary")); title.setTypeface(Typeface.DEFAULT); holder.grayed = true; } else { - itemView.setBackgroundResource(theme.getDrawableId(mContext, "agenda_item_bg_primary")); + itemView.setBackgroundResource(DynamicTheme.getDrawableId(mContext, "agenda_item_bg_primary")); title.setTypeface(Typeface.DEFAULT_BOLD); holder.grayed = false; } diff --git a/src/com/android/calendar/month/MonthByWeekFragment.java b/src/com/android/calendar/month/MonthByWeekFragment.java index 7f56af505..5c14732ee 100644 --- a/src/com/android/calendar/month/MonthByWeekFragment.java +++ b/src/com/android/calendar/month/MonthByWeekFragment.java @@ -301,7 +301,7 @@ public class MonthByWeekFragment extends SimpleDayPickerFragment implements mListView.setOnTouchListener(this); if (!mIsMiniMonth) { - mListView.setBackgroundColor(new DynamicTheme().getColor(getActivity(), "month_bgcolor")); + mListView.setBackgroundColor(DynamicTheme.getColor(getActivity(), "month_bgcolor")); } // To get a smoother transition when showing this fragment, delay loading of events until diff --git a/src/com/android/calendar/month/MonthWeekEventsView.java b/src/com/android/calendar/month/MonthWeekEventsView.java index b6f135010..15c641d78 100644 --- a/src/com/android/calendar/month/MonthWeekEventsView.java +++ b/src/com/android/calendar/month/MonthWeekEventsView.java @@ -228,25 +228,24 @@ public class MonthWeekEventsView extends SimpleWeekView { protected void loadColors(Context context) { Resources res = context.getResources(); - DynamicTheme dynamicTheme = new DynamicTheme(); - - mMonthWeekNumColor = dynamicTheme.getColor(context, "month_week_num_color"); - mMonthNumColor = dynamicTheme.getColor(context, "month_day_number"); - mMonthNumOtherColor = dynamicTheme.getColor(context, "month_day_number_other"); - mMonthNumTodayColor = dynamicTheme.getColor(context, "month_today_number"); - mMonthEventColor = dynamicTheme.getColor(context, "month_event_color"); - mMonthDeclinedEventColor = dynamicTheme.getColor(context, "agenda_item_declined_color"); - mMonthDeclinedExtrasColor = dynamicTheme.getColor(context, "agenda_item_where_declined_text_color"); - mMonthEventExtraColor = dynamicTheme.getColor(context, "month_event_extra_color"); - mMonthEventOtherColor = dynamicTheme.getColor(context, "month_event_other_color"); - mMonthEventExtraOtherColor = dynamicTheme.getColor(context, "month_event_extra_other_color"); - mMonthBGTodayColor = dynamicTheme.getColor(context, "month_today_bgcolor"); - mMonthBGFocusMonthColor = dynamicTheme.getColor(context, "month_focus_month_bgcolor"); - mMonthBGOtherColor = dynamicTheme.getColor(context, "month_other_bgcolor"); - mMonthBGColor = dynamicTheme.getColor(context, "month_bgcolor"); - mDaySeparatorInnerColor = dynamicTheme.getColor(context, "month_grid_lines"); - mTodayAnimateColor = dynamicTheme.getColor(context, "today_highlight_color"); - mClickedDayColor = dynamicTheme.getColor(context, "day_clicked_background_color"); + + mMonthWeekNumColor = DynamicTheme.getColor(context, "month_week_num_color"); + mMonthNumColor = DynamicTheme.getColor(context, "month_day_number"); + mMonthNumOtherColor = DynamicTheme.getColor(context, "month_day_number_other"); + mMonthNumTodayColor = DynamicTheme.getColor(context, "month_today_number"); + mMonthEventColor = DynamicTheme.getColor(context, "month_event_color"); + mMonthDeclinedEventColor = DynamicTheme.getColor(context, "agenda_item_declined_color"); + mMonthDeclinedExtrasColor = DynamicTheme.getColor(context, "agenda_item_where_declined_text_color"); + mMonthEventExtraColor = DynamicTheme.getColor(context, "month_event_extra_color"); + mMonthEventOtherColor = DynamicTheme.getColor(context, "month_event_other_color"); + mMonthEventExtraOtherColor = DynamicTheme.getColor(context, "month_event_extra_other_color"); + mMonthBGTodayColor = DynamicTheme.getColor(context, "month_today_bgcolor"); + mMonthBGFocusMonthColor = DynamicTheme.getColor(context, "month_focus_month_bgcolor"); + mMonthBGOtherColor = DynamicTheme.getColor(context, "month_other_bgcolor"); + mMonthBGColor = DynamicTheme.getColor(context, "month_bgcolor"); + mDaySeparatorInnerColor = DynamicTheme.getColor(context, "month_grid_lines"); + mTodayAnimateColor = DynamicTheme.getColor(context, "today_highlight_color"); + mClickedDayColor = DynamicTheme.getColor(context, "day_clicked_background_color"); mTodayDrawable = res.getDrawable(R.drawable.today_blue_week_holo_light); } diff --git a/src/com/android/calendar/month/SimpleDayPickerFragment.java b/src/com/android/calendar/month/SimpleDayPickerFragment.java index f86b9879e..01d3920ca 100644 --- a/src/com/android/calendar/month/SimpleDayPickerFragment.java +++ b/src/com/android/calendar/month/SimpleDayPickerFragment.java @@ -169,10 +169,9 @@ public class SimpleDayPickerFragment extends ListFragment implements OnScrollLis mTempTime.timezone = tz; Context c = getActivity(); - DynamicTheme theme = new DynamicTheme(); - mSaturdayColor = theme.getColor(c, "month_saturday"); - mSundayColor = theme.getColor(c, "month_sunday"); - mDayNameColor = theme.getColor(c, "month_day_names_color"); + mSaturdayColor = DynamicTheme.getColor(c, "month_saturday"); + mSundayColor = DynamicTheme.getColor(c, "month_sunday"); + mDayNameColor = DynamicTheme.getColor(c, "month_day_names_color"); // Adjust sizes for screen density if (mScale == 0) { diff --git a/src/com/android/calendar/month/SimpleWeekView.java b/src/com/android/calendar/month/SimpleWeekView.java index 2f17d7be2..696a71221 100644 --- a/src/com/android/calendar/month/SimpleWeekView.java +++ b/src/com/android/calendar/month/SimpleWeekView.java @@ -172,14 +172,13 @@ public class SimpleWeekView extends View { super(context); Resources res = context.getResources(); - DynamicTheme theme = new DynamicTheme(); - mBGColor = theme.getColor(context, "month_bgcolor"); - mSelectedWeekBGColor = theme.getColor(context, "month_selected_week_bgcolor"); - mFocusMonthColor = theme.getColor(context, "month_mini_day_number"); - mOtherMonthColor = theme.getColor(context, "month_other_month_day_number"); - mDaySeparatorColor = theme.getColor(context, "month_grid_lines"); - mTodayOutlineColor = theme.getColor(context, "mini_month_today_outline_color"); - mWeekNumColor = theme.getColor(context, "month_week_num_color"); + mBGColor = DynamicTheme.getColor(context, "month_bgcolor"); + mSelectedWeekBGColor = DynamicTheme.getColor(context, "month_selected_week_bgcolor"); + mFocusMonthColor = DynamicTheme.getColor(context, "month_mini_day_number"); + mOtherMonthColor = DynamicTheme.getColor(context, "month_other_month_day_number"); + mDaySeparatorColor = DynamicTheme.getColor(context, "month_grid_lines"); + mTodayOutlineColor = DynamicTheme.getColor(context, "mini_month_today_outline_color"); + mWeekNumColor = DynamicTheme.getColor(context, "month_week_num_color"); mSelectedDayLine = res.getDrawable(R.drawable.dayline_minical_holo_light); if (mScale == 0) { diff --git a/src/com/android/calendar/selectcalendars/SelectCalendarsSimpleAdapter.java b/src/com/android/calendar/selectcalendars/SelectCalendarsSimpleAdapter.java index 2f559edb3..1cd85b5b1 100644 --- a/src/com/android/calendar/selectcalendars/SelectCalendarsSimpleAdapter.java +++ b/src/com/android/calendar/selectcalendars/SelectCalendarsSimpleAdapter.java @@ -87,11 +87,10 @@ public class SelectCalendarsSimpleAdapter extends BaseAdapter implements ListAda mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); mRes = context.getResources(); - DynamicTheme theme = new DynamicTheme(); - mColorCalendarVisible = theme.getColor(context, "calendar_visible"); - mColorCalendarHidden = theme.getColor(context, "calendar_hidden"); - mColorCalendarSecondaryVisible = theme.getColor(context, "calendar_secondary_visible"); - mColorCalendarSecondaryHidden = theme.getColor(context, "calendar_secondary_hidden"); + mColorCalendarVisible = DynamicTheme.getColor(context, "calendar_visible"); + mColorCalendarHidden = DynamicTheme.getColor(context, "calendar_hidden"); + mColorCalendarSecondaryVisible = DynamicTheme.getColor(context, "calendar_secondary_visible"); + mColorCalendarSecondaryHidden = DynamicTheme.getColor(context, "calendar_secondary_hidden"); if (mScale == 0) { mScale = mRes.getDisplayMetrics().density; -- GitLab From 358f3b688e325a25f87c57f06d9437f8ccfd18de Mon Sep 17 00:00:00 2001 From: Gitsaibot Date: Fri, 1 Nov 2019 11:55:53 +0100 Subject: [PATCH 02/95] weblate translation error corrected --- res/values-de/strings.xml | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml index b8e200e3a..8c0b7701d 100644 --- a/res/values-de/strings.xml +++ b/res/values-de/strings.xml @@ -23,11 +23,9 @@ "Morgen" "Heute, %s" "Morgen, %s" - " -\n "Eine Minute" -\n "" -\n "%d Minuten" -\n " + + %1$s, %2$s + "Wiederholung" "(Kein Titel)" @@ -50,16 +48,7 @@ %d Tage - " -\n "Eine Minute" -\n "" -\n "%d Minuten" -\n " - " -\n "Eine Minute" -\n "" -\n "%d Minuten" -\n " + "Woche %d" "Aktualisieren" "Tag anzeigen" -- GitLab From 94694e71f7bbb1ec4272e98918396e80679ca927 Mon Sep 17 00:00:00 2001 From: Jochen Sprickerhof Date: Sun, 10 Nov 2019 19:08:47 +0100 Subject: [PATCH 03/95] Drop newline from weblate error --- res/values-zh-rCN/strings.xml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml index e110fedb7..46975a7bc 100644 --- a/res/values-zh-rCN/strings.xml +++ b/res/values-zh-rCN/strings.xml @@ -238,8 +238,7 @@ %d 项活动 - + -\n%d事件 + +%d事件 "所选活动" "请勿选中 ->" -- GitLab From 79937cab038b34b2e7334cf3c11232169f60c328 Mon Sep 17 00:00:00 2001 From: Jochen Sprickerhof Date: Sun, 10 Nov 2019 19:10:30 +0100 Subject: [PATCH 04/95] Merge string with new lines into one line --- res/values-cy/strings.xml | 5 +---- res/values-es/strings.xml | 8 ++------ res/values-eu/strings.xml | 5 +---- res/values-fr/strings.xml | 5 +---- res/values-in/strings.xml | 5 +---- res/values-iw/strings.xml | 5 +---- res/values-nl/strings.xml | 5 +---- res/values-pl/strings.xml | 5 +---- res/values-pt-rBR/strings.xml | 5 +---- res/values-pt-rPT/strings.xml | 5 +---- res/values-pt/strings.xml | 5 +---- res/values-ru/strings.xml | 5 +---- res/values-szl/strings.xml | 5 +---- 13 files changed, 14 insertions(+), 54 deletions(-) diff --git a/res/values-cy/strings.xml b/res/values-cy/strings.xml index f039f6514..0da38ced2 100644 --- a/res/values-cy/strings.xml +++ b/res/values-cy/strings.xml @@ -129,10 +129,7 @@ Ychwanegu nodyn atgoffa Dim calendrau Cyn medru ychwanegu digwyddiad, rhaid ychwanegu o leiaf un cyfrif Calendr i dy ddyfais a gwneud calendr yn weladwy. Tapia Creu Cyfrif i ychwanegu cyfrif (os wyt ti newydd ychwanegu cyfrif, rho gynnig arall arni ar ôl aros iddo gysoni). Neu tapia Diddymu a sicrhau bod o leiaf un calendr yn weladwy. - Mae Calendr yn gweithio orau gyda chyfrif. -\n -\n• Cael mynediad at dy galendr trwy unrhyw borwr -\n• Cadw copi wrth gefn o dy ddigwyddiadau + Mae Calendr yn gweithio orau gyda chyfrif.\n\n• Cael mynediad at dy galendr trwy unrhyw borwr\n• Cadw copi wrth gefn o dy ddigwyddiadau Ychwanegu cyfrif Calendr: Trefnydd: diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml index 8b1ab053d..881638982 100644 --- a/res/values-es/strings.xml +++ b/res/values-es/strings.xml @@ -96,10 +96,7 @@ "Añadir recordatorio" No hay calendarios "Para añadir eventos, añade al menos una cuenta de Calendar al dispositivo y haz visible un calendario. Para ello, toca Añadir cuenta (si ya lo has hecho, espera a que finalice la sincronización y vuelve a intentarlo). También puedes tocar Cancelar y comprobar que al menos un calendario sea visible." - La aplicación Calendario funciona mejor con una cuenta. -\n -\n• Accede a tu calendario desde cualquier navegador web. -\n• Haz copias de seguridad de tus eventos de forma segura + La aplicación Calendario funciona mejor con una cuenta.\n\n• Accede a tu calendario desde cualquier navegador web.\n• Haz copias de seguridad de tus eventos de forma segura "Añadir cuenta" "Calendario:" "Organizador:" @@ -288,8 +285,7 @@ Nada para importar Elige un archivo para importar Envía evento a: - Lo siento, esta característica no puede funcionar. -\nEtar requiere permisos de lectura y escritura en el calendario para funcionar correctamente + Lo siento, esta característica no puede funcionar.\nEtar requiere permisos de lectura y escritura en el calendario para funcionar correctamente Vista previamente utilizada Vista de Ir a… diff --git a/res/values-eu/strings.xml b/res/values-eu/strings.xml index 27cb94ef5..f7b62b5cf 100644 --- a/res/values-eu/strings.xml +++ b/res/values-eu/strings.xml @@ -65,10 +65,7 @@ Pribatutasuna Gehitu jakinarazpena Egutegirik ez - Egutegiek Kontu batekin hobeto funtzionatzen dute. -\n -\n• Edozein web nabigatzailetik atzitu -\n• Gertaeren babes-kopia segurua egin + Egutegiek Kontu batekin hobeto funtzionatzen dute.\n\n• Edozein web nabigatzailetik atzitu\n• Gertaeren babes-kopia segurua egin Gehitu kontua Egutegia: Antolatzailea: diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml index cb034008d..5ea893c1c 100644 --- a/res/values-fr/strings.xml +++ b/res/values-fr/strings.xml @@ -103,10 +103,7 @@ "Ajouter un rappel" "Aucun agenda" Avant d’ajouter un évènement, vous devez ajouter au moins un agenda à votre appareil et activer sa visibilité. Pour cela, appuyez sur « Ajouter un compte », ou sur « Annuler » si vous pensez qu’au moins un agenda est visible (vérifiez que c’est bien le cas). Si vous venez d’ajouter un compte, patientez jusqu’à la fin de la synchronisation, puis réessayez. - Tirez le meilleur parti d’Etar en utilisant un compte. -\n -\n• Accédez-y depuis n’importe quel navigateur Web -\n• Sauvegardez vos évènements en toute sécurité + Tirez le meilleur parti d’Etar en utilisant un compte.\n\n• Accédez-y depuis n’importe quel navigateur Web\n• Sauvegardez vos évènements en toute sécurité "Ajouter un compte" "Agenda :" "Organisateur :" diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml index d6d14c94d..17b0539ff 100644 --- a/res/values-in/strings.xml +++ b/res/values-in/strings.xml @@ -97,10 +97,7 @@ Tambah pengingat Tidak ada kalender Sebelum anda bisa menambahkan acara, anda harus menambahkan setidaknya satu akun Kalender ke perangkat dan buat kalender terlihat. Sentuh Tambah Akun untuk menambah akun (jika anda baru saja menambahkan akun, tunggu sampai akun selesai disinkronkan dan coba lagi). Atau sentuh Batal dan pastikan setidaknya satu kalender terlihat. - Kalender bekerja lebih baik dengan Akun. -\n -\n• Akses dari peramban web -\n• Cadangkan acara anda dengan aman + Kalender bekerja lebih baik dengan Akun.\n\n• Akses dari peramban web\n• Cadangkan acara anda dengan aman Tambah akun "Kalender:" "Penyelenggara:" diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml index a8e8ab0bf..0ba3252b5 100644 --- a/res/values-iw/strings.xml +++ b/res/values-iw/strings.xml @@ -121,10 +121,7 @@ הוספת תזכורת "אין לוחות שנה" לפני שיתאפשר לך להוסיף אירוע, עליך להוסיף חשבון לוח שנה אחד לפחות למכשיר שלך ושלוח השנה הזה יהיה גלוי. יש לגעת בהוספת חשבון כדי להוסיף חשבון (אם הרגע הוספת חשבון, יש להמתין לסיום סנכרונו ואז לנסות שוב. לחלופין, לגעת בביטול ולוודא שלפחות לוח שנה אחד זמין. - ‚לוח שנה עובד טוב יותר עם חשבון. -\n -\n• גישה מכל דפדפן אינטרנט -\n• גיבוי האירועים שלך באופן מאובטח + ‚לוח שנה עובד טוב יותר עם חשבון.\n\n• גישה מכל דפדפן אינטרנט\n• גיבוי האירועים שלך באופן מאובטח הוספת חשבון לוח שנה: ארגון: diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml index 426d7ffc9..a0333975f 100644 --- a/res/values-nl/strings.xml +++ b/res/values-nl/strings.xml @@ -94,10 +94,7 @@ "Herinnering toevoegen" "Geen agenda\'s" Voordat u een afspraak kunt toevoegen, moet u ten minste één agenda-account aan uw apparaat toevoegen en de agenda zichtbaar maken. Raak \'Account toevoegen\' aan om een account toe te voegen (als u net een account heeft toegevoegd, wacht u tot het synchroniseren is voltooid en probeert u het opnieuw). Of raak \'Annuleren\' aan en zorg ervoor dat er ten minste één agenda zichtbaar is. - Agenda werkt beter met een account. -\n -\n• Toegankelijk via elke webbrowser -\n• Maakt beveiligde back-ups van uw afspraken + Agenda werkt beter met een account.\n\n• Toegankelijk via elke webbrowser\n• Maakt beveiligde back-ups van uw afspraken "Account toevoegen" "Agenda:" "Organisator:" diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml index 226202675..fcedd413f 100644 --- a/res/values-pl/strings.xml +++ b/res/values-pl/strings.xml @@ -111,10 +111,7 @@ "Dodaj przypomnienie" "Brak kalendarzy" "Przed utworzeniem wydarzenia musisz dodać do urządzenia konto z Kalendarzem i ustawić wybrany kalendarz jako widoczny. Wybierz „Dodaj konto” (jeśli właśnie to zrobiłeś, poczekaj na zakończenie synchronizacji i spróbuj ponownie). Możesz też dotknąć Anuluj i upewnić się, że co najmniej jeden kalendarz jest widoczny." - Kalendarz działa lepiej z kontem. -\n -\n• Używaj go w dowolnej przeglądarce -\n• Twórz kopie zapasowe wydarzeń + Kalendarz działa lepiej z kontem.\n\n• Używaj go w dowolnej przeglądarce\n• Twórz kopie zapasowe wydarzeń "Dodaj konto" "Kalendarz:" "Organizator:" diff --git a/res/values-pt-rBR/strings.xml b/res/values-pt-rBR/strings.xml index 6f878735b..e1d65915b 100644 --- a/res/values-pt-rBR/strings.xml +++ b/res/values-pt-rBR/strings.xml @@ -69,10 +69,7 @@ Adicionar lembrete Nenhuma agenda disponível Antes de adicionar um evento, você deve adicionar pelo menos uma conta do Agenda a seu dispositivo e tornar uma agenda visível. Toque em \"Adicionar conta\" para adicionar uma conta (caso tenha adicionado uma conta recentemente, aguarde o fim da sincronização e tente novamente). Ou toque em \"Cancelar\" e certifique-se de que pelo menos uma agenda esteja visível. - O aplicativo Agenda funciona melhor com uma Conta do. -\n -\n• Acesse-o a partir de qualquer navegador da web -\n• Faça backup de seus eventos com segurança + O aplicativo Agenda funciona melhor com uma Conta do.\n\n• Acesse-o a partir de qualquer navegador da web\n• Faça backup de seus eventos com segurança Adicionar conta Agenda: Organizador: diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml index 5e22eb947..3f5c4ef74 100644 --- a/res/values-pt-rPT/strings.xml +++ b/res/values-pt-rPT/strings.xml @@ -103,10 +103,7 @@ "Adicionar lembrete" "Sem calendários" Antes de poder adicionar um evento, tem de adicionar pelo menos uma conta do Calendário e torná-lo visível. Toque em Adicionar conta para adicionar uma conta (se acabou de adicionar uma conta, aguarde que a sincronização esteja concluída). Em alternativa, toque em Cancelar e certifique-se que está visível pelo menos um calendário. - O Calendário funciona melhor com uma conta. -\n -\n• Aceda à conta a partir de qualquer navegador de Internet -\n• Faça uma cópia de segurança dos seus eventos de forma segura + O Calendário funciona melhor com uma conta.\n\n• Aceda à conta a partir de qualquer navegador de Internet\n• Faça uma cópia de segurança dos seus eventos de forma segura "Adicionar conta" "Calendário:" "Organizador:" diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml index c1385b281..b13bb5066 100644 --- a/res/values-pt/strings.xml +++ b/res/values-pt/strings.xml @@ -103,10 +103,7 @@ "Adicionar lembrete" Sem calendários Antes de poder adicionar um evento, tem de adicionar pelo menos uma conta do Calendário e torná-lo visível. Toque em Adicionar conta para adicionar uma conta (se acabou de adicionar uma conta, aguarde que a sincronização esteja concluída). Em alternativa, toque em Cancelar e certifique-se que está visível pelo menos um calendário. - O Calendário funciona melhor com uma conta. -\n -\n• Aceda à conta a partir de qualquer navegador de Internet -\n• Faça uma cópia de segurança dos seus eventos de forma segura + O Calendário funciona melhor com uma conta.\n\n• Aceda à conta a partir de qualquer navegador de Internet\n• Faça uma cópia de segurança dos seus eventos de forma segura "Adicionar conta" Calendário: "Organizador:" diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml index 9381a0177..ef8bda34d 100644 --- a/res/values-ru/strings.xml +++ b/res/values-ru/strings.xml @@ -117,10 +117,7 @@ "Добавить напоминание" "Нет календарей" Добавить событие можно только в видимый календарь, связанный с аккаунтом Google. Нажмите \"Добавить аккаунт\" или, если аккаунт уже добавлен, дождитесь окончания синхронизации и повторите попытку. Либо нажмите \"Отмена\" и сделайте видимым хотя бы один календарь. - Подключите Календарь к аккаунту Google, чтобы: -\n -\n• Всегда иметь под рукой актуальные данные на любом устройстве -\n• Синхронизировать все события, чтобы никогда их не потерять + Подключите Календарь к аккаунту Google, чтобы:\n\n• Всегда иметь под рукой актуальные данные на любом устройстве\n• Синхронизировать все события, чтобы никогда их не потерять "Добавить аккаунт" "Календарь:" "Организатор:" diff --git a/res/values-szl/strings.xml b/res/values-szl/strings.xml index a271fdd90..b8d440b4f 100644 --- a/res/values-szl/strings.xml +++ b/res/values-szl/strings.xml @@ -159,10 +159,7 @@ Wyciszej spōmniynia ô zdarzyniach bez ôkryślōny czas. Edytuj gibke ôdpowiedzi Godzina kōńca - Kalyndorz funguje lepij z kōntym. -\n -\n• Używej go w leda jakij przeglōndarce. -\n• Twōrz kopije ibryczne trefiyń. + Kalyndorz funguje lepij z kōntym.\n\n• Używej go w leda jakij przeglōndarce.\n• Twōrz kopije ibryczne trefiyń. Wychodne spōmniynie Publiczny Skryj nawigacyjo -- GitLab From c2c5bf2ab4fada307b8e56a9aee753e44021433a Mon Sep 17 00:00:00 2001 From: Gitsaibot Date: Tue, 12 Nov 2019 14:27:01 +0100 Subject: [PATCH 05/95] Release new 1.0.19 version (#594) --- AndroidManifest.xml | 4 ++-- build.gradle | 2 +- metadata/ar-AR/changelogs/21.txt | 2 ++ metadata/de-DE/changelogs/21.txt | 2 ++ metadata/en-US/changelogs/21.txt | 2 ++ 5 files changed, 9 insertions(+), 3 deletions(-) create mode 100644 metadata/ar-AR/changelogs/21.txt create mode 100644 metadata/de-DE/changelogs/21.txt create mode 100644 metadata/en-US/changelogs/21.txt diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 853df87b5..07d3d11de 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -20,8 +20,8 @@ + android:versionCode="21" + android:versionName="1.0.19"> - - - - - - + + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/layout/recurrencepicker.xml b/res/layout/recurrencepicker.xml index ed852e64f..9ca402a29 100644 --- a/res/layout/recurrencepicker.xml +++ b/res/layout/recurrencepicker.xml @@ -53,8 +53,8 @@ Date: Wed, 2 Oct 2019 08:18:20 +0000 Subject: [PATCH 20/95] Fix: Handle Calendar intents from mail eventCursor.getCount() is 0 when there is no selection as in our case we are receiving intent from Mail application. --- src/com/android/calendar/GoogleCalendarUriIntentFilter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/com/android/calendar/GoogleCalendarUriIntentFilter.java b/src/com/android/calendar/GoogleCalendarUriIntentFilter.java index 1383ccfd3..4c597ef17 100644 --- a/src/com/android/calendar/GoogleCalendarUriIntentFilter.java +++ b/src/com/android/calendar/GoogleCalendarUriIntentFilter.java @@ -170,7 +170,7 @@ public class GoogleCalendarUriIntentFilter extends Activity { Calendars.CALENDAR_ACCESS_LEVEL + " desc"); if (debug) Log.d(TAG, "Found: " + eventCursor.getCount()); - if (eventCursor == null || eventCursor.getCount() == 0) { + if (eventCursor == null) { Log.i(TAG, "NOTE: found no matches on event with id='" + syncId + "'"); return; } -- GitLab From 6bb0eb7fc55c87cba21354fc5b8df57e2ed4f520 Mon Sep 17 00:00:00 2001 From: Vincent Bourgmayer Date: Wed, 2 Oct 2019 08:22:10 +0000 Subject: [PATCH 21/95] Resolve "Whole day events from outlook not opened correctly" --- src/com/android/calendar/ImportActivity.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/com/android/calendar/ImportActivity.java b/src/com/android/calendar/ImportActivity.java index 04a3c66d9..f418832ea 100644 --- a/src/com/android/calendar/ImportActivity.java +++ b/src/com/android/calendar/ImportActivity.java @@ -180,6 +180,15 @@ public class ImportActivity extends Activity { getLocalTimeFromString(dtEnd, dtEndParam)); } + + //Check if some special property which say it is a "All-Day" event. + + String microsoft_all_day_event = firstEvent.getProperty("X-MICROSOFT-CDO-ALLDAYEVENT"); + if(!TextUtils.isEmpty(microsoft_all_day_event) && microsoft_all_day_event.equals("TRUE")){ + calIntent.putExtra(CalendarContract.EXTRA_EVENT_ALL_DAY, true); + } + + calIntent.putExtra(EditEventActivity.EXTRA_READ_ONLY, true); try { -- GitLab From f130805cf4d03909cee5e31882fab06b13ef73d6 Mon Sep 17 00:00:00 2001 From: Sooraj Date: Sat, 5 Oct 2019 01:24:46 +0530 Subject: [PATCH 22/95] Repeat switch fix button when checked state is true --- res/drawable/switch_thumb.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/drawable/switch_thumb.xml b/res/drawable/switch_thumb.xml index cfb78d2eb..87c51e31f 100644 --- a/res/drawable/switch_thumb.xml +++ b/res/drawable/switch_thumb.xml @@ -17,7 +17,7 @@ - + -- GitLab From 338b9ee0bce09c9ce4498653468e02ff1bc6973c Mon Sep 17 00:00:00 2001 From: "mohit.mali@ftechiz.com" Date: Thu, 28 Nov 2019 15:50:22 +0530 Subject: [PATCH 23/95] Issue: 21 Fixed --- src/com/android/calendar/ImportActivity.java | 21 ++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/com/android/calendar/ImportActivity.java b/src/com/android/calendar/ImportActivity.java index f418832ea..e8f6bc098 100644 --- a/src/com/android/calendar/ImportActivity.java +++ b/src/com/android/calendar/ImportActivity.java @@ -20,9 +20,11 @@ import com.android.calendar.icalendar.VCalendar; import com.android.calendar.icalendar.VEvent; import java.io.File; +import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Arrays; +import java.util.Date; import java.util.LinkedList; import java.util.TimeZone; @@ -180,7 +182,13 @@ public class ImportActivity extends Activity { getLocalTimeFromString(dtEnd, dtEndParam)); } + boolean isAllDay = getLocalTimeFromString(dtEnd, dtEndParam) + - getLocalTimeFromString(dtStart, dtStartParam) == 86400000; + + if (isTimeStartOfDay(dtStart, dtStartParam)) { + calIntent.putExtra(CalendarContract.EXTRA_EVENT_ALL_DAY, isAllDay); + } //Check if some special property which say it is a "All-Day" event. String microsoft_all_day_event = firstEvent.getProperty("X-MICROSOFT-CDO-ALLDAYEVENT"); @@ -200,6 +208,19 @@ public class ImportActivity extends Activity { } } + private boolean isTimeStartOfDay(String dtStart, String dtStartParam) { + // convert to epoch milli seconds + long timeStamp = getLocalTimeFromString(dtStart, dtStartParam); + Date date = new Date(timeStamp); + + DateFormat dateFormat = new SimpleDateFormat("HH:mm"); + String dateStr = dateFormat.format(date); + if (dateStr.equals("00:00")) { + return true; + } + return false; + } + private boolean isValidIntent() { Intent intent = getIntent(); if (intent == null) { -- GitLab From 8e39512b3289f6ac429adac09a5e3bd70eadce08 Mon Sep 17 00:00:00 2001 From: Gitsaibot Date: Wed, 8 Jan 2020 18:22:39 +0100 Subject: [PATCH 24/95] Solve Issues(color should be same as bubbles and repeat switch shouldn't change size) introduced by Fix: Recurrence picker repeat switch! --- res/drawable/switch_thumb.xml | 10 +++++----- res/layout/recurrencepicker.xml | 21 ++++++++++----------- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/res/drawable/switch_thumb.xml b/res/drawable/switch_thumb.xml index 87c51e31f..f843d5325 100644 --- a/res/drawable/switch_thumb.xml +++ b/res/drawable/switch_thumb.xml @@ -18,16 +18,16 @@ - - - + + + - - + + \ No newline at end of file diff --git a/res/layout/recurrencepicker.xml b/res/layout/recurrencepicker.xml index 9ca402a29..a63f4d05a 100644 --- a/res/layout/recurrencepicker.xml +++ b/res/layout/recurrencepicker.xml @@ -54,21 +54,20 @@ android:id="@+id/freqSpinner" style="@style/TextAppearance.RecurrencePickerStyle" android:layout_weight="1" - android:layout_width="wrap_content" + android:layout_width="0dp" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:entries="@array/recurrence_freq" - android:gravity="left" + android:gravity="start" android:padding="0dp" /> + android:layout_marginStart="4dp" /> + android:paddingStart="4dp" > + android:paddingStart="0dp" > -- GitLab From fa4b7b52dfbc69e3f17f242afe2004d46686d336 Mon Sep 17 00:00:00 2001 From: Gitsaibot Date: Wed, 8 Jan 2020 18:37:37 +0100 Subject: [PATCH 25/95] Remove unused resources. See commit Fix: Recurrence picker repeat switch! --- .../switch_thumb_activated_holo_light.9.png | Bin 549 -> 0 bytes .../switch_thumb_disabled_holo_light.9.png | Bin 535 -> 0 bytes .../switch_thumb_holo_light_v2.9.png | Bin 477 -> 0 bytes .../switch_thumb_pressed_holo_light.9.png | Bin 566 -> 0 bytes .../switch_thumb_activated_holo_light.9.png | Bin 351 -> 0 bytes .../switch_thumb_disabled_holo_light.9.png | Bin 350 -> 0 bytes .../switch_thumb_holo_light_v2.9.png | Bin 340 -> 0 bytes .../switch_thumb_pressed_holo_light.9.png | Bin 362 -> 0 bytes .../switch_thumb_activated_holo_light.9.png | Bin 653 -> 0 bytes .../switch_thumb_disabled_holo_light.9.png | Bin 633 -> 0 bytes .../switch_thumb_holo_light_v2.9.png | Bin 595 -> 0 bytes .../switch_thumb_pressed_holo_light.9.png | Bin 660 -> 0 bytes 12 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 res/drawable-hdpi/switch_thumb_activated_holo_light.9.png delete mode 100644 res/drawable-hdpi/switch_thumb_disabled_holo_light.9.png delete mode 100644 res/drawable-hdpi/switch_thumb_holo_light_v2.9.png delete mode 100644 res/drawable-hdpi/switch_thumb_pressed_holo_light.9.png delete mode 100644 res/drawable-mdpi/switch_thumb_activated_holo_light.9.png delete mode 100644 res/drawable-mdpi/switch_thumb_disabled_holo_light.9.png delete mode 100644 res/drawable-mdpi/switch_thumb_holo_light_v2.9.png delete mode 100644 res/drawable-mdpi/switch_thumb_pressed_holo_light.9.png delete mode 100644 res/drawable-xhdpi/switch_thumb_activated_holo_light.9.png delete mode 100644 res/drawable-xhdpi/switch_thumb_disabled_holo_light.9.png delete mode 100644 res/drawable-xhdpi/switch_thumb_holo_light_v2.9.png delete mode 100644 res/drawable-xhdpi/switch_thumb_pressed_holo_light.9.png diff --git a/res/drawable-hdpi/switch_thumb_activated_holo_light.9.png b/res/drawable-hdpi/switch_thumb_activated_holo_light.9.png deleted file mode 100644 index 9c5147efc96653173a7a2c46864144a5486c678a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 549 zcmeAS@N?(olHy`uVBq!ia0y~yUMfc!k1^ zpCa3qZQ!(P%YRrMv3l*?-l?uq(z6!`sd(tUIi^x=nXc2M(A4{Q4d=P_J`->LxjDzz z(9ne?nMaMM_VX{7SdEM2(^pQJrS!}7pQVWr|UKvXxqNtY_fT=L08rE ztIa+|eFuN=iB#^&og4dO>fF1Be+Io&VGh$=zI=t`eaZEIE$s5`%+}5K>knEOxT!qB z+Et+4^K4aK{RGSBMOAOAk1dG#5@wU0ov*x$`NE`Gs!|0Kt;LI%S~T#_e(&hrv39e^ z2AX3`D;()KAco?fM2a$GG6e>_35RyQ7d1jvHX8!n)&?j`g#wgL)LArG!`$^P&$%PO0@V%@G& zp8vG*y=={}N-b*}pg*!T~-~0XhV#b$8bF?cLJhxL)5=_1K zo1LM8t-&jMTGoNTb@MCU3oB_Y*0{z0vwCvJf$I9(CccX-k7w?yy#L+7#p23I>!W9U zTs)RkabMy6As^wO$gPpW*s8N&0;|ZT1}CwA6HHu@L<_EDQ&CDtOL%rLym+SMOvx?g z!Xf3!t5&^wy^F77M(^?Df^)o^9yz+)*p?f1y>!JYuWVy(hAGTqt{1JI&)cLkTitUK z|JIlzX9{fO?w{JE)3qqWG=1eeb|wbD<(Es$X5T$hX!D{jf#czZyLs{DyJOj_qIay3 z{UFR|@K~Ge@7L7mezRwr7CwsKd+zPO56|T%&3q`Eer}WYV)ZWz7#J8BJYD@<);T3K F0RR9o=UD&% diff --git a/res/drawable-hdpi/switch_thumb_holo_light_v2.9.png b/res/drawable-hdpi/switch_thumb_holo_light_v2.9.png deleted file mode 100644 index 9b16618c7462f3d012da132a99eae4213d8c9d12..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 477 zcmeAS@N?(olHy`uVBq!ia0y~yUxiSdP*P$8}a3tpX=5-F~h1tj1fRdHr8uOSzQEK~08i;cBrz{;l#e zS?ayq)5W}n`{(ydkM^H`aLw{;^ZW1Bn{U6BTea$z)pM`2ko#@=6pYFxn1M*C7#0pRqy9B)~q^v$;yDC;{Ej8+j++d zYxos=f^E$ulQ+bzU%RzT*eT*s81pfS*!$nb4y1f+_|s5rA>+m%cIx_ys)B@n{;&Ut zizPWIvWbvM1l^y>u)yKoZ5j0$rKc40-v-Dp%5>oS-m&Lk`lP#&C$wMlHQ3Kq_9Rcn~*YI6(}Ib_!|FfcH9y85}Sb4q9e0IKT8-v9sr diff --git a/res/drawable-hdpi/switch_thumb_pressed_holo_light.9.png b/res/drawable-hdpi/switch_thumb_pressed_holo_light.9.png deleted file mode 100644 index ea54380fc4ce96ded6bba67d4bb1723537c4cfdb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 566 zcmeAS@N?(olHy`uVBq!ia0y~yU@5 zxUWeeucj%li#z_H`%CE^ub4~1Sq{F7@hFew4Ew-;gJZHm>ZCiftLyca1aRH0u(>R9 zK7FR^xhJR3%styVp`|0?OVa3+xaykc-P*259h2tAu;Rbb^rUb&#OP*aQo2G(gWO=4)v_&`296CzQ62UnegHL lRl2u-emGyR;`xV7gm3--9rylqGB7YOc)I$ztaD0e0sv^X1>OJv diff --git a/res/drawable-mdpi/switch_thumb_activated_holo_light.9.png b/res/drawable-mdpi/switch_thumb_activated_holo_light.9.png deleted file mode 100644 index 3d7c236abb742d7a9d7cb1e72d17bcf30890c82e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 351 zcmeAS@N?(olHy`uVBq!ia0y~yU@&7~V36ZrV_;xN-}SbQfq{Xg*vT`5gM)*kh9jke zfq{Xuz$3Dlfq}adgc;3Go?gqqz{u$7;usRq`gVq)-(d#<*ZUTIOIeQcimESI`dB10 z@JQ|s9wFa#jVo3-JYrcn!AWS-Nhuo>2gjE;UDlZTN9BJ1JHPA>&#F^`7wn&Jkhkue zJb8}YzS+~RwVd94{PVArn!8G+U2d$qqH+(vJ$&_Ox9V{%wezR{`rI#-vcLRi<5dTj zSt}0kwq+W1uRXl3ZIkJ*fuJKF8trt{S-T@e17nmu7O5t(ToLrA1)q9 zlU!pMX881F-MN=HI}%MdPGelqnH?uy+;e;L{Jl*QMqCS&?nZ2P__J^KrQ=hR&I^XR mF8Qn?_v@s!XmIF0hNWlyW`0*K{Kvq+z~JfX=d#Wzp$Pz`mYM

WZ7tH0L;rZFsD6+{kJC8r##a?`;ZBsbEllBAv}P;orNxGKEVk3g&bi m*m-wy#e4nxp*}7jxP8w==nMPg&0%0*VDNPHb6Mw<&;$Vci;jW- diff --git a/res/drawable-mdpi/switch_thumb_holo_light_v2.9.png b/res/drawable-mdpi/switch_thumb_holo_light_v2.9.png deleted file mode 100644 index b3cee3f7e76860bc6698d0e06f224aa362013293..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 340 zcmeAS@N?(olHy`uVBq!ia0y~yU@&7~V36ZrV_;xN-}SbQfq{Xg*vT`5gM)*kh9jke zfq{Xuz$3Dlfq}adgc;3Go?gqq!0^q}#W5tJ_3ey}UPl~6T+hdf8M29Whg{oM#$6Y? zswOn+_7}5jVU8O*T6BwYV+6RnYd5bJes*9>`Mtz@JZBD@i65}PR%yPwCs@%k+r~V9 zF=y`WdnUfc`Y*LSUB4yD9G|}KwVje>pyAir{p(k~Dx9U}uD@30)vjwc=eHjaZp`EA z<~_V&^WS-|R4278kyZE?(32V|a`s1GZce+gxn|eTevyrLG?I1(9w}Pf@zhQ5bg$Ah zX;&Tdt{eI}!cS#xPI$m9!)x$?&4$5y%M5+91I7nm-Yi@v@UttPx!hrrrf2~}T%+ZL tjmIWFIyEtO$z)(;5C#SY22WQ%mvv4FO#q#oi8}xQ diff --git a/res/drawable-mdpi/switch_thumb_pressed_holo_light.9.png b/res/drawable-mdpi/switch_thumb_pressed_holo_light.9.png deleted file mode 100644 index 670dc2e99a1b720f31120d3285c14292424a2396..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 362 zcmeAS@N?(olHy`uVBq!ia0y~yU@&7~V36ZrV_;xN-}SbQfq{Xg*vT`5gM)*kh9jke zfq{Xuz$3Dlfq}adgc;3Go?gqqz{un2;usRq`gVq)-(d#<*Z(;=>W)QTS}QEw`5gKu z6wR2!+G*tO5YxbX;X+H7TF{z|!|NXVGmD6b%=3NH`^=H@svPqD>XePaW?PAf#-=0>6#>V-^ny%cM$gqI>w_44f^$Y%({=cc+v8atXK=E!w zIm4mvcc&-5)9$Gkm?ZGhw)1#i<@yAbkF3Xef@YTMpH^mIU|{fc^>bP0l+XkK+%1l> diff --git a/res/drawable-xhdpi/switch_thumb_activated_holo_light.9.png b/res/drawable-xhdpi/switch_thumb_activated_holo_light.9.png deleted file mode 100644 index ca48bd866c2de51b9266bb8ed99a48f0a7257713..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 653 zcmeAS@N?(olHy`uVBq!ia0y~yV8~)%V6fs~V_;y2Sbrvgfq{Xg*vT`5gM)*kh9jke zfq{Xuz$3Dlfq}adgc;3Go?gqqz@+c#;uumf=k1;SUBZDP$3NbmJ2S_u#aArZL4^Bg zlC-0?{DDJBtlskvT$;Y|8>5) zZ<(ZjN_}=t>clal*q?{k>AS+BpN!$UlL)gRA=wv2QAm)aiqo1Wi(TU^ch zZ(OM$-_mb3^#Vt(wLg}>|Jq+)?p~&edtrqAuaJGl>uf7`mi|0-)xEjyy`z9n(j=wn z&o?j!i0Os$eO>kS{Qla%pT2zfxVQC^#iA;A+2dKuv;X8}JgRt@EFK&eUzYmt&Wi9p z?Gx{ermbh(b9t7lamdD;I=^sc`)P}K4A;A5doJmo6w~#%;F1rc2*adf8oRQmUaxtqZhL7r3=XUT&BRA=s5*d*S<=b`m` z`gwI#g^KnEq2JqH)8Joj*Tx0bfK8GI1536S;2fly!cs8@fyB%S+J6Rq0&GX_9eVx7ig1k?$O%nUt zR~+rXhJCBe8K#^np5w;g!XVqQz@~lWVYz?dIW8_PH;cU3uSCbo h{C_F0ru2jNgVh$d#m~GKGB7YOc)I$ztaD0e0ssXK5_kXr diff --git a/res/drawable-xhdpi/switch_thumb_disabled_holo_light.9.png b/res/drawable-xhdpi/switch_thumb_disabled_holo_light.9.png deleted file mode 100644 index c3d80f0eb33fccb012fcf57cd12391fd74731a20..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 633 zcmeAS@N?(olHy`uVBq!ia0y~yV8~)%V6fs~V_;y2Sbrvgfq{Xg*vT`5gM)*kh9jke zfq{Xuz$3Dlfq}adgc;3Go?gqqz$ESI;uumf=k1+?UAF>6j(vQub}_<>ZAz1~W2{Kp z#c#a7q8>TF$o|T^>BTYw-kTvS1h-sG$;ub+1M>2jO%_pP5733k4!J8r42bg4A<`_gr<&+oqb zZk0*big|&N)AoM7SMPKAOZ2qVtsOkGKHDh1{9X5O@BazQUfMRSk7~|n^SZTd@5g)n z>XSWrAEYnw_sDwxH}>{6a|R&>E%wQ;Oc%cYT_VBeQla)&Rmquy@m}@S+NHmqDjj+r zp)YcEzs@i7HlwD6Jqa4h5~nz*%yjxK8^@`r&?4}bQP|1j-a@)_cVB*4GF_!`Zp2}O z2UUC9mSwKmr1L!>#@ws)sTjlJpEdu|wnnY}WTP)|-?aF}u6Hq^pzopr0EH4E!2kdN diff --git a/res/drawable-xhdpi/switch_thumb_holo_light_v2.9.png b/res/drawable-xhdpi/switch_thumb_holo_light_v2.9.png deleted file mode 100644 index 39592ac80bf27ff6af7c18b15fe50732c4c92555..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 595 zcmeAS@N?(olHy`uVBq!ia0y~yV8~)%V6fs~V_;y2Sbrvgfq{Xg*vT`5gM)*kh9jke zfq{Xuz$3Dlfq}adgc;3Go?gqq!1&eE#WAE}&f7a1^KJ!59Q{~a7_@t>gU`l@#e0}e zP1?$wf4eumZnq4}(_wAF-%iO&s6h19}Uxdz`8oT*ZQ!D2`|H^8AIE) z-1)0kRmH3g^FRIcQjXc>fcC?Qn{MXVz5V`s_v4QiTXL;iT>jm)d>%9J`Qn!)R#x6-t$ST~*<|;sRaWn7wdOvU<2)^OozCfU*TA0g-FJB#@(rvW z`#R6{TfQiB7Q=(;``Z1-D+n9BF}mG#>5^+Xs_YVXf}`zO2NJ#&)6 zWoiApUnd4=2ywYOE%eY3;cQh}7@#83)#5}2LCqGg#5V6U>09IySQao8H|2h0tIk5)6Z!fS*@@A0deg0#1Lxo!CkJ@9i&m_unb!7jq^uGAvc$(_gsctSVPsG!| mG*x};eq8_epcBUr#?tqbFBb4!6lY*yVDNPHb6Mw<&;$TrRQ&Y- diff --git a/res/drawable-xhdpi/switch_thumb_pressed_holo_light.9.png b/res/drawable-xhdpi/switch_thumb_pressed_holo_light.9.png deleted file mode 100644 index 4acb32b1933965edafd1566c95536d9bee6a52ec..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 660 zcmeAS@N?(olHy`uVBq!ia0y~yV8~)%V6fs~V_;y2Sbrvgfq{Xg*vT`5gM)*kh9jke zfq{Xuz$3Dlfq}adgc;3Go?gqqz+~p>;uumf=j|Q)Zed4>;~($8$ve0E$nK}_csR1; zHwcQ!d_8o@$T)rxBOP2 zrKc^Y-1_{-k7Xn8!{0Ywp8WCkvg2aQ?!&(>FaKo!_~z}4-{$WA9+#I_GLJpMo@-Oo z!==uv8YXvdt1Y*&to!`$=;EE1G#2ezl=kk}f!I@yUl!&y{m`g(F(2u6$`P zY8XBQW{aH-IGVKc&GGJt#V#I^s!`kxTRer5)`a_BW)EQSklMVWF6&5qn4;VCcCK|`6^%&P$>t0z8aTvAl`vnr^G z<^81ZtJ0lA*Xw_{d~(f=H+ma3Z-2b4>ZE9;ZhX# zxbQa&9fe!xm_7E77mIhl&#=X-xT8!XVecyQ4SiFtb{+b4*M&jOAz Date: Sun, 10 Nov 2019 12:13:52 +0000 Subject: [PATCH 26/95] Translated using Weblate (Hebrew) Currently translated at 100.0% (262 of 262 strings) Translation: Etar-Calendar/Strings Translate-URL: https://hosted.weblate.org/projects/etar-calendar/strings/he/ --- res/values-iw/strings.xml | 42 ++++++++++++++------------------------- 1 file changed, 15 insertions(+), 27 deletions(-) diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml index 0ba3252b5..9055074bc 100644 --- a/res/values-iw/strings.xml +++ b/res/values-iw/strings.xml @@ -21,13 +21,9 @@ "אורחים" "היום" "מחר" - היום ב־%s - - מחר ב־%s - - - %1$s, %2$s - + היום ב־%s + מחר ב־%s + %1$s, %2$s "חזרה" "(אין כותרת)" @@ -185,8 +181,7 @@ יומי - כל יומיים - + כל יומיים כל %d ימים כל %d ימים @@ -302,34 +297,26 @@ "חזרה" "ללא חזרה" - כל יום - - כל יומיים - + כל <<xliff:g xmlns:xliff=\"urn:oasis:names:tc:xliff:document:1.2\" id=\"count\">יום</xliff:g> + כל יומיים כל %d ימים כל %d ימים - כל שבוע - - כל שבועיים - + כל שבוע + כל שבועיים כל %d שבועות כל %d שבועות - כל חודש - - כל חודשיים - + כל חודש + כל חודשיים כל %d חודשים כל %d חודשים - כל שנה - - כל שנתיים - + כל שנה + כל שנתיים כל %d שנים כל %d שנים @@ -340,8 +327,7 @@ "למספר אירועים" - עבור אירוע אחד - + עבור אירוע אחד עבור %d אירועים עבור %d אירועים עבור %d אירועים @@ -403,4 +389,6 @@ מועד התחלה וסיום מועד התחלה וסיום מתחת לאירוע סנכרון התראות + מספר שורות מרבי באירוע + נדרשות התראות בחזית לטובת סנכרון התרעות פנימי. נא להשתיק \ No newline at end of file -- GitLab From 26e79db7896c4bf28336bb1a44ee156526aa5820 Mon Sep 17 00:00:00 2001 From: nautilusx Date: Sun, 10 Nov 2019 20:15:53 +0000 Subject: [PATCH 27/95] Translated using Weblate (German) Currently translated at 100.0% (276 of 276 strings) Translation: Etar-Calendar/Strings Translate-URL: https://hosted.weblate.org/projects/etar-calendar/strings/de/ --- res/values-de/strings.xml | 47 +++++++++++++++++---------------------- 1 file changed, 21 insertions(+), 26 deletions(-) diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml index 8c0b7701d..be5c1ac21 100644 --- a/res/values-de/strings.xml +++ b/res/values-de/strings.xml @@ -23,29 +23,24 @@ "Morgen" "Heute, %s" "Morgen, %s" - - %1$s, %2$s - + %1$s, %2$s "Wiederholung" "(Kein Titel)" - Eine Minute - - %d Minuten + 1 Minute + %d Minuten 1 Min. - - %d Min. + %d Min. - "1 Stunde" - "%d Stunden" + 1 Stunde + %d Stunden 1 Tag - - %d Tage + %d Tage "Woche %d" @@ -200,8 +195,8 @@ Version "Kalender" - "+1" - "+%d" + +1 + +%d "Keine anstehenden Termine" "Experimentell" @@ -238,32 +233,32 @@ "+ neuer Termin" Termin %1$s von %2$s. - "1 Ereignis" - "%d Ereignisse" + 1 Ereignis + %d Ereignisse - "+1 Termin" - "+%d Termine" + +1 Termin + +%d Termine "Ausgewähltes Ereignis" "NICHT aktivieren ->" "Wiederholen" "Einmaliger Termin" - "Nach %d Tag" - "Alle %d Tage" + Nach %d Tag + Alle %d Tage - "Nach %d Woche" - "Alle %d Wochen" + Nach %d Woche + Alle %d Wochen - "Nach %d Monat" - "Alle %d Monate" + Nach %d Monat + Alle %d Monate - "Nach %d Jahr" - "Alle %d Jahre" + Nach %d Jahr + Alle %d Jahre "am gleichen Tag des Monats" "Dauerhaft" -- GitLab From 808a306b20e29bf512d78c9d9c6da463da3038be Mon Sep 17 00:00:00 2001 From: Aled Powell Date: Sun, 10 Nov 2019 21:09:49 +0000 Subject: [PATCH 28/95] Translated using Weblate (Welsh) Currently translated at 97.1% (268 of 276 strings) Translation: Etar-Calendar/Strings Translate-URL: https://hosted.weblate.org/projects/etar-calendar/strings/cy/ --- res/values-cy/strings.xml | 71 ++++++++++++++------------------------- 1 file changed, 26 insertions(+), 45 deletions(-) diff --git a/res/values-cy/strings.xml b/res/values-cy/strings.xml index 0da38ced2..9128e511c 100644 --- a/res/values-cy/strings.xml +++ b/res/values-cy/strings.xml @@ -20,61 +20,42 @@ Dim munudau 1 munud - - %d funud - - %d munud - - %d munud - - %d munud + %d funud + %d munud + %d munud + %d munud - 0 mun - 1 mun - 2 fun - - %d mun - - %d mun - - %d mun + %d mun + 1 fun + %d fun + %d mun + %d mun + %d mun - 0 awr + %d oriau 1 awr - 2 awr - - %d awr - - %d awr - - %d awr + %d awr + %d awr + %d awr + %d awr - 0 diwrnodau + %d diwrnodoau 1 diwrnod - 2 ddiwrnod - - %d diwrnod - - %d diwrnod - - %d diwrnod + %d ddiwrnod + %d diwrnod + %d diwrnod + %d diwrnod - wythnos %d - - wythnos %d - - wythnos %d - - wythnos %d - - wythnos %d - - wythnos %d - + wythnos %d + wythnos %d + wythnos %d + wythnos %d + wythnos %d + wythnos %d Ail-gysoni Dangos diwrnod -- GitLab From 6a96ba26c5cf9a07725e4324e2d64b783e74d946 Mon Sep 17 00:00:00 2001 From: zmni Date: Mon, 11 Nov 2019 21:26:31 +0000 Subject: [PATCH 29/95] Translated using Weblate (Indonesian) Currently translated at 99.3% (274 of 276 strings) Translation: Etar-Calendar/Strings Translate-URL: https://hosted.weblate.org/projects/etar-calendar/strings/id/ --- res/values-in/strings.xml | 31 ++++++++++--------------------- 1 file changed, 10 insertions(+), 21 deletions(-) diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml index 17b0539ff..4c1a776e5 100644 --- a/res/values-in/strings.xml +++ b/res/values-in/strings.xml @@ -21,34 +21,25 @@ "Tamu" "Hari ini" "Besok" - Hari ini pada jam %s - - Besok pada jam %s - - - %1$s, %2$s - + Hari ini pada jam %s + Besok pada jam %s + %1$s, %2$s Pengulangan "(Tanpa judul)" - - %d menit + %d menit - - %d mnt + %d mnt - - %d jam + %d jam - - %d hari + %d hari - minggu %d - + minggu %d "Segarkan" "Tampilkan hari" @@ -204,8 +195,7 @@ "Versi bentukan" "Kalender" - +%d - + +%d "Tidak ada acara kalender yang akan datang" "Eksperimental" @@ -242,8 +232,7 @@ "+ Acara baru" Acara %1$s dari %2$s. - - %d acara + %d acara +%d acara -- GitLab From c2c6eb83168cebca4f2240397f88437461be0dbb Mon Sep 17 00:00:00 2001 From: junseong kim Date: Mon, 11 Nov 2019 12:51:03 +0000 Subject: [PATCH 30/95] Translated using Weblate (Korean) Currently translated at 100.0% (262 of 262 strings) Translation: Etar-Calendar/Strings Translate-URL: https://hosted.weblate.org/projects/etar-calendar/strings/ko/ --- res/values-ko/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml index 5d70ec28e..ff638b854 100644 --- a/res/values-ko/strings.xml +++ b/res/values-ko/strings.xml @@ -328,4 +328,6 @@ 시작시간과 끝나는시간 이벤트보다 낮은 시작 및 종료 시간 이벤트의 최대 라인 수 + 동기화 경고 + Foreground 알림 내부 경계 태세를 동기화에 필요하다. 음소거 해달라 \ No newline at end of file -- GitLab From d5bf1ce3fa27eaed51450a04edc2767e6dd19b6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Allan=20Nordh=C3=B8y?= Date: Sun, 10 Nov 2019 21:32:23 +0000 Subject: [PATCH 31/95] =?UTF-8?q?Translated=20using=20Weblate=20(Norwegian?= =?UTF-8?q?=20Bokm=C3=A5l)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 99.6% (261 of 262 strings) Translation: Etar-Calendar/Strings Translate-URL: https://hosted.weblate.org/projects/etar-calendar/strings/nb_NO/ --- res/values-nb/strings.xml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml index 801c1c22e..53b8ec1c9 100644 --- a/res/values-nb/strings.xml +++ b/res/values-nb/strings.xml @@ -23,9 +23,7 @@ "I morgen" "I dag kl. %s" "I morgen kl. %s" - - %1$s, %2$s - + %1$s, %2$s "Gjentas" "(Ingen tittel)" -- GitLab From ef62c9040f64aade85453e0ba6bdb4fb262e32d5 Mon Sep 17 00:00:00 2001 From: Xiang Xu Date: Fri, 15 Nov 2019 01:44:48 +0000 Subject: [PATCH 32/95] Translated using Weblate (Chinese (Simplified)) Currently translated at 100.0% (276 of 276 strings) Translation: Etar-Calendar/Strings Translate-URL: https://hosted.weblate.org/projects/etar-calendar/strings/zh_Hans/ --- res/values-zh-rCN/strings.xml | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml index 46975a7bc..6ecd82eb8 100644 --- a/res/values-zh-rCN/strings.xml +++ b/res/values-zh-rCN/strings.xml @@ -29,20 +29,24 @@ "重复" "(无标题)" - + %d 分钟 + - + %d 分钟 + - + %d 小时 + - + %d + "第 %d 周" @@ -234,8 +238,9 @@ "+ 新建活动" "第 %1$s 个活动,共 %2$s 个。" - + %d 项活动 + +%d事件 -- GitLab From d6cf858f6a6b42fd72973b6c83b211ea610788c4 Mon Sep 17 00:00:00 2001 From: solokot Date: Sun, 17 Nov 2019 21:25:12 +0000 Subject: [PATCH 33/95] Translated using Weblate (Russian) Currently translated at 100.0% (276 of 276 strings) Translation: Etar-Calendar/Strings Translate-URL: https://hosted.weblate.org/projects/etar-calendar/strings/ru/ --- res/values-ru/strings.xml | 112 +++++++++++++------------------------- 1 file changed, 37 insertions(+), 75 deletions(-) diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml index ef8bda34d..ddf0a5ac1 100644 --- a/res/values-ru/strings.xml +++ b/res/values-ru/strings.xml @@ -21,54 +21,35 @@ Участники "Сегодня" "Завтра" - Сегодня, %s - - Завтра, %s - - - %1$s, %2$s - + Сегодня, %s + Завтра, %s + %1$s, %2$s "Повторять" "(Нет заголовка)" - - %d минута - - %d минуты - - %d минут + %d минута + %d минуты + %d минут - - %d мин. - - %d мин. - - %d мин. + %d мин. + %d мин. + %d мин. - - %d час - - %d часа - - %d часов + %d час + %d часа + %d часов - - %d день - - %d дня - - %d дней + %d день + %d дня + %d дней - неделя %d - - неделя %d - - неделя %d - + неделя %d + неделя %d + неделя %d "Обновить" "Показать день" @@ -151,17 +132,12 @@ "Ваш ответ…" "Организатор:" "Напоминания" - сегодня, %1$s - - вчера, %1$s - - завтра, %1$s - + сегодня, %1$s + вчера, %1$s + завтра, %1$s "Загрузка…" - Нажмите, чтобы увидеть события до %1$s - - Нажмите, чтобы увидеть события после %1$s - + Нажмите, чтобы увидеть события до %1$s + Нажмите, чтобы увидеть события после %1$s "Поиск в моих календарях" "Сведения" "Изменить" @@ -172,15 +148,11 @@ "Удалить все" "Отложить" Однократное событие - до %s - + до %s - - %d раз - - %d раза - - %d раз + %d раз + %d раза + %d раз Ежедневно @@ -232,12 +204,9 @@ "Версия сборки" "Календарь" - и ещё %d - - и ещё %d - - и ещё %d - + и ещё %d + и ещё %d + и ещё %d В календаре нет предстоящих событий "Экспериментальная версия" @@ -274,12 +243,9 @@ Создать событие Событие %1$s из %2$s. - - %d событие - - %d события - - %d событий + %d событие + %d события + %d событий Ещё %d событие @@ -313,16 +279,12 @@ ежемесячно в этот день "Всегда" До определённой даты - До %s - + До %s Несколько раз - - %d повтор - - %d повтора - - %d повторов + %d повтор + %d повтора + %d повторов "изменить дату окончания" По умолчанию -- GitLab From e979d1daf45a3dd92116149d1b1d29ae99417285 Mon Sep 17 00:00:00 2001 From: Osoitz Date: Fri, 22 Nov 2019 05:24:33 +0000 Subject: [PATCH 34/95] Translated using Weblate (Basque) Currently translated at 96.4% (266 of 276 strings) Translation: Etar-Calendar/Strings Translate-URL: https://hosted.weblate.org/projects/etar-calendar/strings/eu/ --- res/values-eu/strings.xml | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/res/values-eu/strings.xml b/res/values-eu/strings.xml index f7b62b5cf..3cad907bf 100644 --- a/res/values-eu/strings.xml +++ b/res/values-eu/strings.xml @@ -252,28 +252,23 @@ Bihar %s(e)tan Minutu 1 - - %d minutu + %d minutu Min 1 - - %d min + %d min Ordu 1 - - %d ordu + %d ordu Egun 1 - - %d egun + %d egun - 1. Astea - - %d. Astea + 1. astea + %d. astea Gertaera bat gehitu aurretik, gutxienez Egutegi bat gehitu behar duzu zure gailuan eta egutegia ikusgarri bezala markatu. Ukitu Gehitu Kontua kontu bat gehitzeko (kontu bat gehitu baduzu, itxaron sinkronizazioa bukatu arte eta saiatu berriz). Edo ukitu Utzi eta ziurtatu gutxienez egutegi bat dagoela ikusgarri. Ukitu gertaerak ikusteko %1$s baino geroago -- GitLab From a4775ae48d165845cbf171dc72482f4fa0cf99fc Mon Sep 17 00:00:00 2001 From: Kintu Date: Sat, 23 Nov 2019 14:04:40 +0000 Subject: [PATCH 35/95] Translated using Weblate (Basque) Currently translated at 97.5% (269 of 276 strings) Translation: Etar-Calendar/Strings Translate-URL: https://hosted.weblate.org/projects/etar-calendar/strings/eu/ --- res/values-eu/strings.xml | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/res/values-eu/strings.xml b/res/values-eu/strings.xml index 3cad907bf..0091c58ca 100644 --- a/res/values-eu/strings.xml +++ b/res/values-eu/strings.xml @@ -8,9 +8,7 @@ Gonbidatuak Gaur Bihar - - %1$s, %2$s - + %1$s, %2$s Errepikapena (Izenbururik ez) Eguneratu @@ -119,8 +117,7 @@ Egunero - - %d egunero + %d egunero Lanegun guztietan (Al-Ol) Hilabetero @@ -218,10 +215,8 @@ %s arte - - %d gertaerarentzat - - %d gertaerentzat + %d gertaerarentzat + %d gertaerentzat aldatu bukera data Etar-ek egutegiaren irakurketa eta idazketa baimenak behar ditu ondo funtzionatzeko. Saiatu berri mesedez. @@ -280,7 +275,7 @@ %1$d astero %2$s(e)tan Pertsonalizatua (ezin da pertsonalizatu telefonoan) - Bidaiatzen zaudela zure etxeko ordu-zonan egutegiak eta gertaerak erakusten ditu. + Bidaiatzen zaudela zure etxeko ordu-zonan egutegiak eta gertaerak erakusten ditu Galdetu utzi gerokorako atzerapen oroitzapena, jakinarazpenentan Erabili beti errepikapen atzerapen lehenetsia Ezarri errepikapen atzerapena @@ -288,8 +283,7 @@ Errepikapen atzerapen lehenetsia +1 - +%d - + +%d Ez dago hurrengo egutegiko gertaerarik Isildu gertaera gogorarazlea zehaztutako denbora bitartean. @@ -297,8 +291,7 @@ %2$s(e)tik. Gertaera 1 - - %d gertaerak + %d gertaerak +1 gertaera -- GitLab From 16d567a948c5f4e0640eed361031a4a736deafc2 Mon Sep 17 00:00:00 2001 From: Kintu Date: Fri, 22 Nov 2019 11:58:51 +0000 Subject: [PATCH 36/95] Translated using Weblate (Catalan) Currently translated at 99.2% (260 of 262 strings) Translation: Etar-Calendar/Strings Translate-URL: https://hosted.weblate.org/projects/etar-calendar/strings/ca/ --- res/values-ca/strings.xml | 55 +++++++++++++++++++++++++++++++++++---- 1 file changed, 50 insertions(+), 5 deletions(-) diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml index 357c5db37..6a9467eb8 100644 --- a/res/values-ca/strings.xml +++ b/res/values-ca/strings.xml @@ -23,9 +23,7 @@ "Demà" "Avui a les %s" "Demà a les %s" - - %1$s, %2$s - + %1$s, %2$s "Repetició" "(Sense títol)" @@ -76,7 +74,7 @@ "Convidats" "S\'ha creat un esdeveniment." "S\'ha desat l\'esdeveniment." - "Esdeveniment buit no creat" + Esdeveniment buit no creat. "S\'enviaran les invitacions." "S\'enviaran les actualitzacions." "Desa" @@ -115,7 +113,7 @@ "Truca" "Respostes ràpides" "Edita respostes predeterminades en enviar correus als convidats" - "Edita resp. ràpid." + Edita respostes ràpides "Resposta ràpida" "Tria una resposta ràpida" "No s\'ha pogut trobar un programa de correu electrònic" @@ -281,4 +279,51 @@ Fixa el retard de la repetició Temps de retard de la repetició predefinit Retard de la repetició predefinit + Ves a… + Ha respost sí. + Ha respost potser. + Ha respost no. + Tema + Clar + Fosc + Negre + Color primari + Color primari + Dies per setmana + Dies per setmana + Duració d\'esdeveniment per defecte + Reporta problema + Etar requereix permisos per a llegir i escriure al calendari per a funcionar correctament. Si us plau, prova-ho de nou. + Ho sentim, aquesta característica no pot funcionar. Etar requereix permisos per a llegir i escriure al calendari per a funcionar correctament + Confidencial + 0 minuts + 15 minuts + 30 minuts + 1 hora + 1.5 hores + 2 hores + Comparteix + No hi ha aplicació de mapes instal·lada + Vista per defecte + Vista utilitzada prèviament + S\'han trobat problemes mentre es compartia l\'esdeveniment + Envia l\'esdeveniment a: + Exporta a la targeta SD + Esdeveniment exportat satisfactòriament: %1s + Importar l\'esdeveniment + No hi ha res per a importar + L\'importació a calendari ha fallat + No s\'ha pogut entendre la data proporcionada: %s + Escull un fitxer per a importar + Configuració de visualització + Disseny de vista mensual (vertical) + Disseny de vista mensual (horitzontal) + Veure detalls + Mostra l\'hora + Mostra la ubicació + No mostrar l\'hora + Només l\'hora d\'inici + Hora d\'inici i finalització + Hora d\'inici i de finalització sota l\'esdeveniment + Número màxim de línies a l\'esdeveniment \ No newline at end of file -- GitLab From 5a9ec8db1fa16fefdd16eba8785bda7ad716c779 Mon Sep 17 00:00:00 2001 From: Kintu Date: Tue, 26 Nov 2019 19:26:17 +0000 Subject: [PATCH 37/95] Translated using Weblate (Catalan) Currently translated at 99.6% (261 of 262 strings) Translation: Etar-Calendar/Strings Translate-URL: https://hosted.weblate.org/projects/etar-calendar/strings/ca/ --- res/values-ca/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml index 6a9467eb8..43dc7f904 100644 --- a/res/values-ca/strings.xml +++ b/res/values-ca/strings.xml @@ -326,4 +326,5 @@ Hora d\'inici i finalització Hora d\'inici i de finalització sota l\'esdeveniment Número màxim de línies a l\'esdeveniment + Sincronització d\'alertes \ No newline at end of file -- GitLab From 2c57715ec1a6b22e1f7fb04e8f2fff5bb856b783 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Marques?= Date: Mon, 25 Nov 2019 22:27:27 +0000 Subject: [PATCH 38/95] Translated using Weblate (Portuguese (Portugal)) Currently translated at 100.0% (276 of 276 strings) Translation: Etar-Calendar/Strings Translate-URL: https://hosted.weblate.org/projects/etar-calendar/strings/pt_PT/ --- res/values-pt-rPT/strings.xml | 36 ++++++++++++----------------------- 1 file changed, 12 insertions(+), 24 deletions(-) diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml index 3f5c4ef74..2bcb17943 100644 --- a/res/values-pt-rPT/strings.xml +++ b/res/values-pt-rPT/strings.xml @@ -21,40 +21,30 @@ "Convidados" "Hoje" "Amanhã" - Hoje, às %s - - Amanhã, às %s - - - %1$s, %2$s - + Hoje, às %s + Amanhã, às %s + %1$s, %2$s Repetições (sem título) 1 minuto - - %d minutos + %d minutos - 1 min. - - %d min. + 1 min + %d min 1 hora - - %d horas + %d horas 1 dia - - %d dias + %d dias - semana %d - - semana %d - + semana %d + semana %d "Atualizar" "Mostrar dia" @@ -215,8 +205,7 @@ "Calendário" +1 - +%d - + +%d "Sem eventos futuros no calendário" "Experimental" @@ -254,8 +243,7 @@ Evento %1$s de %2$s. 1 evento - - %d eventos + %d eventos +1 evento -- GitLab From 1ec9edbd98f71c98e9c5acd77026b55ccc0de1b6 Mon Sep 17 00:00:00 2001 From: BennyBeat Date: Thu, 28 Nov 2019 07:53:09 +0000 Subject: [PATCH 39/95] Translated using Weblate (Catalan) Currently translated at 100.0% (262 of 262 strings) Translation: Etar-Calendar/Strings Translate-URL: https://hosted.weblate.org/projects/etar-calendar/strings/ca/ --- res/values-ca/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml index 43dc7f904..35c9c0226 100644 --- a/res/values-ca/strings.xml +++ b/res/values-ca/strings.xml @@ -327,4 +327,5 @@ Hora d\'inici i de finalització sota l\'esdeveniment Número màxim de línies a l\'esdeveniment Sincronització d\'alertes + És necessari una notificació principal per sincronitzar el servei intern d\'alertes; silencieu-la \ No newline at end of file -- GitLab From 830f022f26921e86290475c3ed817f965bb62fe1 Mon Sep 17 00:00:00 2001 From: El Pirujo Date: Sat, 30 Nov 2019 16:14:25 +0000 Subject: [PATCH 40/95] Translated using Weblate (Spanish) Currently translated at 100.0% (276 of 276 strings) Translation: Etar-Calendar/Strings Translate-URL: https://hosted.weblate.org/projects/etar-calendar/strings/es/ --- res/values-es/strings.xml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml index 881638982..d625602d3 100644 --- a/res/values-es/strings.xml +++ b/res/values-es/strings.xml @@ -33,8 +33,8 @@ "%d minutos" - "1 minuto" - "%d minutos" + 1 min. + %d mins. "1 hora" @@ -46,8 +46,7 @@ Etiqueta para mostrar la semana del año [CHAR LIMIT=16] - semana %d - + semana %d "Actualizar" "Mostrar día" @@ -241,7 +240,7 @@ "%d eventos" - +1 evento. + +1 evento +%d eventos "Evento seleccionado" -- GitLab From 1a4a6921ba64678c3c74130166a85a34b4f59893 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96zcan=20O=C4=9Fuz?= Date: Mon, 2 Dec 2019 02:22:56 +0000 Subject: [PATCH 41/95] Translated using Weblate (Turkish) Currently translated at 99.6% (261 of 262 strings) Translation: Etar-Calendar/Strings Translate-URL: https://hosted.weblate.org/projects/etar-calendar/strings/tr/ --- res/values-tr/strings.xml | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml index 46a303167..c98b9bd52 100644 --- a/res/values-tr/strings.xml +++ b/res/values-tr/strings.xml @@ -301,4 +301,35 @@ 1 saat 1.5 saat 2 saat + Paylaş + Herhangi bir harita uygulaması yüklü değil + Varsayılan görünüm + Önceden kullanılan görünüm + Hatırlatıcı için erteleme süresini sor + Hatırlatıcı her ertelendiğinde erteleme süresini sor + Her zaman varsayılan erteleme süresini kullan + Erteleme süresini ayarla + Varsayılan erteleme süresi + Varsayılan erteleme süresi + Etkinlik paylaşılırken bir hata oluştu + Etkinliği şuna gönder: + SD karta aktar + Etkinlik başarıyla dışarıya aktarıldı: %1s + Etkinliği içeri aktar + İçeri aktarılacak hiçbir şey yok + Takvime aktarma başarısız oldu + Girilen tarih anlaşılamadı: %s + İçe aktarmak için dosya seçin + Ayarları görüntüle + Aylık görünüm (Dik) + Aylık görünüm (Yatay) + Ayrıntıları görüntüle + Zamanı görüntüle + Yeri görüntüle + Saati gösterme + Sadece başlangıç saati + Başlangıç ve bitiş saatleri + Etkinliğin altında başlangıç ve bitiş saatleri + Etkinlikteki maksimum satır sayısı + Uyarı eşitlemesi \ No newline at end of file -- GitLab From 0bb7f5aea9f2bd8e43f649de7dd7b495913a0ff8 Mon Sep 17 00:00:00 2001 From: nautilusx Date: Sat, 14 Dec 2019 18:10:34 +0000 Subject: [PATCH 42/95] Translated using Weblate (German) Currently translated at 100.0% (276 of 276 strings) Translation: Etar-Calendar/Strings Translate-URL: https://hosted.weblate.org/projects/etar-calendar/strings/de/ --- res/values-de/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml index be5c1ac21..0afc17437 100644 --- a/res/values-de/strings.xml +++ b/res/values-de/strings.xml @@ -327,5 +327,5 @@ Start- und Endzeit unterhalb des Termins Maximale Zeilenanzahl pro Kalendereintrag Alarm Synchronisation - Benachrichtigung welche für die interne Alarm Synchronisation benötigt wird. Bitte stumm schalten + Vordergrundbenachrichtigung für die interne Alarmsynchronisation erforderlich. Bitte stumm schalten \ No newline at end of file -- GitLab From 4885776864163fe0db7ec67e627764b0dfdbc87f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89frit?= Date: Mon, 23 Dec 2019 20:52:18 +0000 Subject: [PATCH 43/95] Translated using Weblate (French) Currently translated at 100.0% (276 of 276 strings) Translation: Etar-Calendar/Strings Translate-URL: https://hosted.weblate.org/projects/etar-calendar/strings/fr/ --- res/values-fr/strings.xml | 76 ++++++++++++++++----------------------- 1 file changed, 30 insertions(+), 46 deletions(-) diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml index 5ea893c1c..ba143d5e3 100644 --- a/res/values-fr/strings.xml +++ b/res/values-fr/strings.xml @@ -21,39 +21,31 @@ "Invités" Aujourd’hui "Demain" - Aujourd’hui, %s - + Aujourd’hui, %s "Demain, %s" - - %1$s, %2$s - + %1$s, +\n%2$s "Fréquence" "(Sans titre)" 1 minute - - %d minutes + %d minutes 1 min - - %d min + %d min - 1 heure - - %d heures + 1 h + %d h 1 jour - - %d jours + %d jours - semaine %d - - semaine %d - + semaine %d + semaine %d "Actualiser" "Afficher le jour" @@ -70,8 +62,8 @@ "Paramètres" "Agendas à afficher" "Rechercher" - "Masquer commandes" - "Afficher commandes" + Masquer les commandes + Afficher les commandes "Agendas à afficher" "synchronisé" "non synchronisé" @@ -107,7 +99,7 @@ "Ajouter un compte" "Agenda :" "Organisateur :" - Sélectionnez la couleur de l’évènement + Sélectionner la couleur de l’évènement Couleur de l’évènement Choisir la couleur de l’agenda par défaut Couleur de l’agenda @@ -137,15 +129,12 @@ Réponse personnalisée… "Organisateur :" "Rappels" - aujourd’hui, %1$s - + aujourd’hui, %1$s "hier, %1$s" "demain, %1$s" "Chargement…" - Appuyez pour afficher les évènements avant le %1$s - - Appuyez pour afficher les évènements après le %1$s - + Appuyez pour afficher les évènements avant le %1$s + Appuyez pour afficher les évènements après le %1$s "Rechercher dans mes agendas" Détails "Modifier" @@ -156,8 +145,7 @@ "Tout supprimer" "Répéter" Évènement ponctuel - ; jusqu’au %s - + ; jusqu’au %s "; une seule fois" "; %d fois" @@ -168,10 +156,8 @@ Jours en semaine (lun–ven) - Hebdomadaire, le %2$s - - Toutes les %1$d semaines le %2$s - + Hebdomadaire, le %2$s + Toutes les %1$d semaines le %2$s Mensuellement Annuellement @@ -226,8 +212,8 @@ "Version" "Agenda" - "+ 1" - "+ %d" + +1 + +%d Aucun évènement à venir "Test" @@ -265,8 +251,7 @@ Évènement %1$s sur %2$s. 1 évènement - - %d évènements + %d évènements +1 évènement @@ -277,26 +262,25 @@ "Répéter" "Ne jamais répéter" - "Tous les %d jour" - "Tous les %d jours" + Tous les jours + Tous les %d jours - "Toutes les %d semaine" - "Toutes les %d semaines" + Toutes les semaines + Toutes les %d semaines - Tous les %d mois + Tous les mois Tous les %d mois - "Tous les %d an" - "Tous les %d ans" + Tous les ans + Tous les %d ans "le même jour chaque mois" "Toujours" Jusqu’à une date - Jusqu’au %s - + Jusqu’au %s Pour une série d’évènements Pour %d évènement -- GitLab From 5ee84a656f5579b9c6b67dcd847528d25376442f Mon Sep 17 00:00:00 2001 From: Osoitz Date: Sun, 29 Dec 2019 10:42:17 +0000 Subject: [PATCH 44/95] Translated using Weblate (Basque) Currently translated at 100.0% (276 of 276 strings) Translation: Etar-Calendar/Strings Translate-URL: https://hosted.weblate.org/projects/etar-calendar/strings/eu/ --- res/values-eu/strings.xml | 48 ++++++++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 16 deletions(-) diff --git a/res/values-eu/strings.xml b/res/values-eu/strings.xml index 0091c58ca..53b468c16 100644 --- a/res/values-eu/strings.xml +++ b/res/values-eu/strings.xml @@ -8,7 +8,9 @@ Gonbidatuak Gaur Bihar - %1$s, %2$s + + %1$s, %2$s + Errepikapena (Izenbururik ez) Eguneratu @@ -117,7 +119,8 @@ Egunero - %d egunero + + %d egunero Lanegun guztietan (Al-Ol) Hilabetero @@ -215,8 +218,10 @@ %s arte - %d gertaerarentzat - %d gertaerentzat + + %d gertaerarentzat + + %d gertaerentzat aldatu bukera data Etar-ek egutegiaren irakurketa eta idazketa baimenak behar ditu ondo funtzionatzeko. Saiatu berri mesedez. @@ -247,23 +252,29 @@ Bihar %s(e)tan Minutu 1 - %d minutu + + %d minutu Min 1 - %d min + + %d min Ordu 1 - %d ordu + + %d ordu Egun 1 - %d egun + + %d egun - 1. astea - %d. astea + + %d. astea + + %d. astea Gertaera bat gehitu aurretik, gutxienez Egutegi bat gehitu behar duzu zure gailuan eta egutegia ikusgarri bezala markatu. Ukitu Gehitu Kontua kontu bat gehitzeko (kontu bat gehitu baduzu, itxaron sinkronizazioa bukatu arte eta saiatu berriz). Edo ukitu Utzi eta ziurtatu gutxienez egutegi bat dagoela ikusgarri. Ukitu gertaerak ikusteko %1$s baino geroago @@ -283,7 +294,8 @@ Errepikapen atzerapen lehenetsia +1 - +%d + +%d + Ez dago hurrengo egutegiko gertaerarik Isildu gertaera gogorarazlea zehaztutako denbora bitartean. @@ -291,7 +303,8 @@ %2$s(e)tik. Gertaera 1 - %d gertaerak + + %d gertaerak +1 gertaera @@ -300,23 +313,26 @@ Egunero - %d egunero + %d egunetik behin Astero - %d astero + %d asterik behik Hilabetero - %d hilabetero + %d hilabeterik behin Urtero - %d urtero + %d urterik behin Zenbait gertaerentzako Hasiera eta bukaera denbora gertaera azpian + Gertaeraren gehieneko lerro kopurua + Alerta-sinkronizazioa + Lehen planoko jakinarazpena beharrezkoa da barne alertak sinkronizatzeko. Mesedez, isildu \ No newline at end of file -- GitLab From 0954f4ec24021c2cfc41b47c3e0bfee254510f77 Mon Sep 17 00:00:00 2001 From: Milo Ivir Date: Tue, 31 Dec 2019 18:27:30 +0000 Subject: [PATCH 45/95] Translated using Weblate (Croatian) Currently translated at 100.0% (262 of 262 strings) Translation: Etar-Calendar/Strings Translate-URL: https://hosted.weblate.org/projects/etar-calendar/strings/hr/ --- res/values-hr/strings.xml | 107 +++++++++++++++++++++++++------------- 1 file changed, 72 insertions(+), 35 deletions(-) diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml index 14115631e..ca660fd72 100644 --- a/res/values-hr/strings.xml +++ b/res/values-hr/strings.xml @@ -29,23 +29,40 @@ "Ponavljanje" "(bez naslova)" - "1 minuta" - "%d minuta" + 1 minuta + + %d minute + + %d minuta - "1 minuta" - "%d minuta" + 1 min + + %d min + + %d min - "1 sat" - "%d sati" + 1 sat + + %d sata + + %d sati - "1 dan" - "%d dana" + 1 dan + + %d dana + + %d dana - "tjedan %d" + + %d. tjedan + + %d. tjedan + + %d. tjedan "Osvježi" "Prikaži dan" @@ -94,7 +111,10 @@ "Dodavanje podsjetnika" "Nema kalendara" "Prije nego što ćete moći dodati događaj morate dodati barem jedan račun usluge Kalendar na svoj uređaj i kalendar učiniti vidljivim. Da biste dodali račun, dodirnite Dodaj račun (ako ste upravo dodali račun, pričekajte dovrši sinkronizaciju i pokušajte ponovno) ili dodirnite Odustani i provjerite je li barem jedan kalendar vidljiv." - "Kalendar radi bolje s Google računom."\n\n"• Pristupite mu iz bilo kojeg web-preglednika."\n"• Stvorite sigurnosnu kopiju svojih događaja." + Kalendar radi bolje s računom. +\n +\n• Pristupite mu iz bilo kojeg web-preglednika +\n• Stvorite sigurnosnu kopiju svojih događaja "Dodavanje računa" "Kalendar:" "Organizator:" @@ -146,17 +166,23 @@ "Jednokratni događaj" "; do %s" - "; jedanput" - "; toliko puta: %d" + ; jedanput + ; %d puta + ; %d puta - "Dnevno" - "Svakih toliko dana: %d" + Dnevno + Svaka %d dana + Svakih %d dana "Svaki dan u tjednu (pon–pet)" - "Svaki tjedan, %2$s" - "Svaki %1$d. tjedan, %2$s" + Svaki tjedan na %2$s + + Svaka %1$d tjedna na %2$s + + Svakih %1$d tjedana na %2$s + "Mjesečno" "Godišnje" @@ -197,8 +223,11 @@ "Međuverzija" "Kalendar" - "+1" - "+%d" + +1 + +%d + + +%d + "Nema skorih događaja kalendara" "Eksperimentalno" @@ -235,35 +264,40 @@ "+ Novi događaj" "%1$s od %2$s događaja." - "1 događaj" - "%d događaja" + 1 događaj + + %d događaja + + %d događaja - "još 1 događaj" - "još ovoliko događaja: %d" + + 1 događaj + + %d događaja + + %d događaja "Odabrani događaj" "NE provjeravaj ->" "Ponovi" Nikad se ne ponavlja - Svakog %d dana - Svakog %d dana - + Svakih %d dan + Svaka %d dana + Svakih %d dana - Svakog %d tjedna - Svakog %d tjedna - + Svaki tjedan + Svaka %d tjedna + Svakih %d tjedna - "Svakog %d. mjeseca" - "Svakog %d. mjeseca" + Svaki mjesec + Svaka %d mjeseca + Svakih %d mjeseci - Svake %d godine - Svake %d godine - + Svake godine + Svake %d godine + Svakih %d godina istog dana svakog mjeseca "Zauvijek" @@ -273,7 +307,7 @@ Za %d događaj Za %d događaja - + Za %d događaja "promjena datuma završetka" Zadano @@ -294,7 +328,7 @@ Zadano trajanje događaja Prijavi probleme Da bi radio ispravno Etar zahtijeva dozvolu za čitanje i pisanje kalendara. Pokušajte ponovo. - Žao mi je ovo ne može raditi. Da bi radio ispravno Etar zahtijeva dozvolu za čitanje i pisanje kalendara. + Ova funkcija nažalost ne radi. Da bi radio ispravno, Etar zahtijeva dozvolu za čitanje i pisanje kalendara Povjerljivo 0 minuta 15 minuta @@ -331,4 +365,7 @@ Samo vrijeme početka Vrijeme početka i završetka Vrijeme početka i završetka ispod događaja + Maksimalan broj redaka u događaju + Sinkronizacija alarma + Neophodna obavijest za unutarnju sinkronizaciju alarma. Isključi zvuk \ No newline at end of file -- GitLab From 707eeb48583927703574a245206ee1dda9ce2672 Mon Sep 17 00:00:00 2001 From: A Date: Wed, 8 Jan 2020 21:04:51 +0000 Subject: [PATCH 46/95] Translated using Weblate (Hebrew) Currently translated at 100.0% (276 of 276 strings) Translation: Etar-Calendar/Strings Translate-URL: https://hosted.weblate.org/projects/etar-calendar/strings/he/ --- res/values-iw/strings.xml | 69 +++++++++++++++++++++++---------------- 1 file changed, 41 insertions(+), 28 deletions(-) diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml index 9055074bc..04499ba5d 100644 --- a/res/values-iw/strings.xml +++ b/res/values-iw/strings.xml @@ -21,13 +21,17 @@ "אורחים" "היום" "מחר" - היום ב־%s - מחר ב־%s - %1$s, %2$s + היום ב־%s + + מחר ב־%s + + + %1$s, %2$s + "חזרה" "(אין כותרת)" - דקה + This is the label for a 1-minute reminder.1 דקה %d דקות @@ -36,7 +40,7 @@ %d דקות - דקה + דקה אחת %d דקות @@ -45,7 +49,7 @@ %d דקות - שעה + שעה אחת שעתיים %d שעות @@ -53,7 +57,7 @@ %d שעות - יום + יום אחד יומיים %d ימים @@ -70,26 +74,26 @@ שבוע %d - רענון - הצגת יום + רענן + הצג יום "סדר יום" "יום" "שבוע" "חודש" - הצגת אירוע + הצג אירוע "אירוע חדש" - עריכת אירוע - מחיקת אירוע + ערוך אירוע + מחק אירוע "היום" "הגדרות" לוחות שנה להצגה - חיפוש - הסתרת פקדים - הצגת פקדים + חפש + הסתר פקדים + הצג פקדים "לוחות שנה להצגה" "מסונכרן" "לא מסונכרן" - חשבון זה אינו מסונכרן כך שייתכן שלוחות השנה שלך אינם עדכניים. + חשבון זה אינו מסונכרן לכן ייתכן כי לוחות השנה שלך אינם עדכניים. חשבונות וסנכרון לוחות שנה לסנכרון לוחות שנה לסנכרון @@ -181,7 +185,8 @@ יומי - כל יומיים + כל יומיים + כל %d ימים כל %d ימים @@ -287,7 +292,7 @@ %d אירועים - +אירוע אחד + אירוע אחד +%d אירועים +%d אירועים +%d אירועים @@ -298,25 +303,32 @@ "ללא חזרה" כל <<xliff:g xmlns:xliff=\"urn:oasis:names:tc:xliff:document:1.2\" id=\"count\">יום</xliff:g> - כל יומיים + כל יומיים + כל %d ימים כל %d ימים - כל שבוע - כל שבועיים + כל שבוע + + כל שבועיים + כל %d שבועות כל %d שבועות - כל חודש - כל חודשיים + כל חודש + + כל חודשיים + כל %d חודשים כל %d חודשים - כל שנה - כל שנתיים + כל שנה + + כל שנתיים + כל %d שנים כל %d שנים @@ -327,7 +339,8 @@ "למספר אירועים" - עבור אירוע אחד + עבור אירוע אחד + עבור %d אירועים עבור %d אירועים עבור %d אירועים @@ -359,7 +372,7 @@ שעה שעה וחצי שעתיים - שיתוף + שתף לא מותקן יישומון מפות תצוגת בררת מחדל תצוגה שהשתמשו בה בעבר @@ -378,7 +391,7 @@ הייבוא ללוח השנה נכשל לא ניתן לפענח את התאריך שסופק: %s נא לבחור קובץ לייבוא - הצגת הגדרות + הצג הגדרות פריסת תצוגת חודש (לאורך) פריסת תצוגת חודש (לרוחב) הצגת פרטים -- GitLab From d04cb2cab73190eb59a3adb20fbdf85de93288e6 Mon Sep 17 00:00:00 2001 From: Milo Ivir Date: Fri, 10 Jan 2020 23:54:02 +0000 Subject: [PATCH 47/95] Translated using Weblate (Croatian) Currently translated at 100.0% (262 of 262 strings) Translation: Etar-Calendar/Strings Translate-URL: https://hosted.weblate.org/projects/etar-calendar/strings/hr/ --- res/values-hr/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml index ca660fd72..aa4b01d49 100644 --- a/res/values-hr/strings.xml +++ b/res/values-hr/strings.xml @@ -84,7 +84,7 @@ "sinkronizirano" "nije sinkronizirano" "Ovaj se račun ne sinkronizira pa vaši kalendari možda nisu ažurni." - "Računi & sinkronizacija" + Računi i sinkronizacija "Kalendari za sinkronizaciju" "Kalendari za sinkronizaciju" "Naziv događaja" -- GitLab From ecbda3a420b1eb65f2b4e665df7d56fef4bafb90 Mon Sep 17 00:00:00 2001 From: nautilusx Date: Sat, 11 Jan 2020 16:14:49 +0000 Subject: [PATCH 48/95] Translated using Weblate (German) Currently translated at 95.7% (265 of 277 strings) Translation: Etar-Calendar/Strings Translate-URL: https://hosted.weblate.org/projects/etar-calendar/strings/de/ --- res/values-de/strings.xml | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml index 0afc17437..3655be502 100644 --- a/res/values-de/strings.xml +++ b/res/values-de/strings.xml @@ -23,24 +23,30 @@ "Morgen" "Heute, %s" "Morgen, %s" - %1$s, %2$s + + %1$s, %2$s + "Wiederholung" "(Kein Titel)" 1 Minute - %d Minuten + + %d Minuten 1 Min. - %d Min. + + %d Min. 1 Stunde - %d Stunden + + %d Stunden 1 Tag - %d Tage + + %d Tage "Woche %d" @@ -196,7 +202,8 @@ "Kalender" +1 - +%d + +%d + "Keine anstehenden Termine" "Experimentell" @@ -234,7 +241,8 @@ Termin %1$s von %2$s. 1 Ereignis - %d Ereignisse + + %d Ereignisse +1 Termin @@ -288,7 +296,7 @@ Nichts zu importieren Importiere Termin Import zum Kalender ist fehlgeschlagen - Konnte Datum nicht erkennen: %s + Datum konnte nicht erkannt werden: %s Termin erfolgreich exportiert: %1s Export auf SD-Karte Zugesagt. @@ -328,4 +336,5 @@ Maximale Zeilenanzahl pro Kalendereintrag Alarm Synchronisation Vordergrundbenachrichtigung für die interne Alarmsynchronisation erforderlich. Bitte stumm schalten + Zeitzone konnte nicht erkannt werden: %s \ No newline at end of file -- GitLab From 12b4088f69c23fd20238a5701dbcaf8e20d68790 Mon Sep 17 00:00:00 2001 From: zmni Date: Sat, 11 Jan 2020 13:58:06 +0000 Subject: [PATCH 49/95] Translated using Weblate (Indonesian) Currently translated at 99.3% (275 of 277 strings) Translation: Etar-Calendar/Strings Translate-URL: https://hosted.weblate.org/projects/etar-calendar/strings/id/ --- res/values-in/strings.xml | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml index 4c1a776e5..9db43a977 100644 --- a/res/values-in/strings.xml +++ b/res/values-in/strings.xml @@ -21,25 +21,34 @@ "Tamu" "Hari ini" "Besok" - Hari ini pada jam %s - Besok pada jam %s - %1$s, %2$s + Hari ini pada jam %s + + Besok pada jam %s + + + %1$s, %2$s + Pengulangan "(Tanpa judul)" - %d menit + + %d menit - %d mnt + + %d mnt - %d jam + + %d jam - %d hari + + %d hari - minggu %d + minggu %d + "Segarkan" "Tampilkan hari" @@ -195,7 +204,8 @@ "Versi bentukan" "Kalender" - +%d + +%d + "Tidak ada acara kalender yang akan datang" "Eksperimental" @@ -232,7 +242,8 @@ "+ Acara baru" Acara %1$s dari %2$s. - %d acara + + %d acara +%d acara @@ -319,4 +330,5 @@ Waktu mulai dan selesai Waktu mulai dan selesai di bawah acara Jumlah baris maks. acara + Tidak bisa memvalidasi zona waktu yang diimpor: %s \ No newline at end of file -- GitLab From 9cb864b99fd41df0b972f7cdb8ebc8b5f0ad91b6 Mon Sep 17 00:00:00 2001 From: El Pirujo Date: Sat, 11 Jan 2020 14:53:08 +0000 Subject: [PATCH 50/95] Translated using Weblate (Spanish) Currently translated at 100.0% (277 of 277 strings) Translation: Etar-Calendar/Strings Translate-URL: https://hosted.weblate.org/projects/etar-calendar/strings/es/ --- res/values-es/strings.xml | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml index d625602d3..54e3450b8 100644 --- a/res/values-es/strings.xml +++ b/res/values-es/strings.xml @@ -34,7 +34,8 @@ 1 min. - %d mins. + + %d mins. "1 hora" @@ -46,7 +47,8 @@ Etiqueta para mostrar la semana del año [CHAR LIMIT=16] - semana %d + semana %d + "Actualizar" "Mostrar día" @@ -236,8 +238,9 @@ "Añadir evento" Evento %1$s de %2$s. - "1 evento" - "%d eventos" + 1 evento. + + %d eventos. +1 evento @@ -332,4 +335,5 @@ Número máximo de líneas en el evento Sincronizar alerta Se requiere notificación en primer plano para sincronizar la alerta interna. Por favor, silenciar + No entiendo la zona horaria proporcionada: %s \ No newline at end of file -- GitLab From 83cf527863aaf828829ed917bc0372693ac19294 Mon Sep 17 00:00:00 2001 From: Gitsaibot Date: Sun, 12 Jan 2020 17:15:00 +0100 Subject: [PATCH 51/95] Remove external datetimepicker (#613) * Remove old datetimepicker --- build.gradle | 35 -------- external/datetimepicker | 1 - res/values/colors.xml | 1 + .../android/calendar/AllInOneActivity.java | 15 ++-- .../calendar/event/EditEventFragment.java | 16 +--- .../android/calendar/event/EditEventView.java | 87 +++++-------------- .../RecurrencePickerDialog.java | 21 ++--- 7 files changed, 40 insertions(+), 136 deletions(-) delete mode 160000 external/datetimepicker diff --git a/build.gradle b/build.gradle index ddba4b984..d25f00405 100644 --- a/build.gradle +++ b/build.gradle @@ -77,40 +77,6 @@ project(':external:colorpicker') { } } -project(':external:datetimepicker') { - apply plugin: 'android-library' - - dependencies { - implementation 'androidx.legacy:legacy-support-v4:1.0.0' - } - - android { - compileSdkVersion 29 - buildToolsVersion '29.0.2' - - defaultConfig { - minSdkVersion 19 - targetSdkVersion 29 - } - - sourceSets { - main { - manifest.srcFile 'AndroidManifest.xml' - java.srcDirs = ['src'] - resources.srcDirs = ['src'] - aidl.srcDirs = ['src'] - renderscript.srcDirs = ['src'] - res.srcDirs = ['res'] - assets.srcDirs = ['assets'] - } - } - - lintOptions { - abortOnError false - } - } -} - project(':external:timezonepicker') { apply plugin: 'android-library' @@ -182,7 +148,6 @@ dependencies { implementation 'com.google.android.material:material:1.0.0' implementation project(':external:calendar') implementation project(':external:colorpicker') - implementation project(':external:datetimepicker') implementation project(':external:timezonepicker') implementation project(':external:chips') } diff --git a/external/datetimepicker b/external/datetimepicker deleted file mode 160000 index 76c4c4ed9..000000000 --- a/external/datetimepicker +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 76c4c4ed90f3ccf8c4a269d7907cef121d484d6c diff --git a/res/values/colors.xml b/res/values/colors.xml index d888f1075..19662a8ae 100644 --- a/res/values/colors.xml +++ b/res/values/colors.xml @@ -269,6 +269,7 @@ #212121 #ff737373 #ffffff + #cccccc #ffffff diff --git a/src/com/android/calendar/AllInOneActivity.java b/src/com/android/calendar/AllInOneActivity.java index 2f286446b..0e2de036b 100644 --- a/src/com/android/calendar/AllInOneActivity.java +++ b/src/com/android/calendar/AllInOneActivity.java @@ -20,6 +20,7 @@ import android.Manifest; import android.animation.Animator; import android.animation.Animator.AnimatorListener; import android.animation.ObjectAnimator; +import android.app.DatePickerDialog; import android.app.Fragment; import android.app.FragmentManager; import android.app.FragmentTransaction; @@ -63,6 +64,7 @@ import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.accessibility.AccessibilityEvent; +import android.widget.DatePicker; import android.widget.LinearLayout; import android.widget.RelativeLayout; import android.widget.RelativeLayout.LayoutParams; @@ -77,7 +79,6 @@ import com.android.calendar.agenda.AgendaFragment; import com.android.calendar.alerts.AlertService; import com.android.calendar.month.MonthByWeekFragment; import com.android.calendar.selectcalendars.SelectVisibleCalendarsFragment; -import com.android.datetimepicker.date.DatePickerDialog; import java.io.File; import java.util.List; @@ -860,7 +861,6 @@ public class AllInOneActivity extends AbstractCalendarActivity implements EventH mController.refreshCalendars(); return true; } else if (itemId == R.id.action_today) { - viewType = ViewType.CURRENT; t = new Time(mTimeZone); t.setToNow(); extras |= CalendarController.EXTRA_GOTO_TODAY; @@ -874,9 +874,9 @@ public class AllInOneActivity extends AbstractCalendarActivity implements EventH t = todayTime; } - DatePickerDialog datePickerDialog = DatePickerDialog.newInstance(new DatePickerDialog.OnDateSetListener() { - @Override - public void onDateSet(DatePickerDialog dialog, int year, int monthOfYear, int dayOfMonth) { + DatePickerDialog.OnDateSetListener datePickerListener = new DatePickerDialog.OnDateSetListener() { + + public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) { Time selectedTime = new Time(mTimeZone); selectedTime.year = year; selectedTime.month = monthOfYear; @@ -884,8 +884,9 @@ public class AllInOneActivity extends AbstractCalendarActivity implements EventH long extras = CalendarController.EXTRA_GOTO_TIME | CalendarController.EXTRA_GOTO_DATE; mController.sendEvent(this, EventType.GO_TO, selectedTime, null, selectedTime, -1, ViewType.CURRENT, extras, null, null); } - }, t.year, t.month, t.monthDay); - datePickerDialog.show(getFragmentManager(), "datePickerDialog"); + }; + DatePickerDialog datePickerDialog = new DatePickerDialog(this,datePickerListener,t.year, t.month,t.monthDay); + datePickerDialog.show(); } else if (itemId == R.id.action_hide_controls) { mHideControls = !mHideControls; diff --git a/src/com/android/calendar/event/EditEventFragment.java b/src/com/android/calendar/event/EditEventFragment.java index aff0b7f64..a9c9a954a 100644 --- a/src/com/android/calendar/event/EditEventFragment.java +++ b/src/com/android/calendar/event/EditEventFragment.java @@ -135,8 +135,6 @@ public class EditEventFragment extends Fragment implements EventHandler, OnColor private boolean mSaveOnDetach = true; private boolean mIsReadOnly = false; private boolean mShowColorPalette = false; - private boolean mTimeSelectedWasStartTime; - private boolean mDateSelectedWasStartDate; private InputMethodManager mInputMethodManager; private final View.OnClickListener mActionBarListener = new View.OnClickListener() { @Override @@ -323,8 +321,7 @@ public class EditEventFragment extends Fragment implements EventHandler, OnColor } else { view = inflater.inflate(R.layout.edit_event, null); } - mView = new EditEventView(mContext, view, mOnDone, mTimeSelectedWasStartTime, - mDateSelectedWasStartDate); + mView = new EditEventView(mContext, view, mOnDone); if (Build.VERSION.SDK_INT >= 23 && ContextCompat.checkSelfPermission(mContext, Manifest.permission.READ_CALENDAR) @@ -387,14 +384,6 @@ public class EditEventFragment extends Fragment implements EventHandler, OnColor if (savedInstanceState.containsKey(BUNDLE_KEY_READ_ONLY)) { mIsReadOnly = savedInstanceState.getBoolean(BUNDLE_KEY_READ_ONLY); } - if (savedInstanceState.containsKey("EditEventView_timebuttonclicked")) { - mTimeSelectedWasStartTime = savedInstanceState.getBoolean( - "EditEventView_timebuttonclicked"); - } - if (savedInstanceState.containsKey(BUNDLE_KEY_DATE_BUTTON_CLICKED)) { - mDateSelectedWasStartDate = savedInstanceState.getBoolean( - BUNDLE_KEY_DATE_BUTTON_CLICKED); - } if (savedInstanceState.containsKey(BUNDLE_KEY_SHOW_COLOR_PALETTE)) { mShowColorPalette = savedInstanceState.getBoolean(BUNDLE_KEY_SHOW_COLOR_PALETTE); } @@ -618,9 +607,6 @@ public class EditEventFragment extends Fragment implements EventHandler, OnColor outState.putSerializable(BUNDLE_KEY_EVENT, mEventBundle); outState.putBoolean(BUNDLE_KEY_READ_ONLY, mIsReadOnly); outState.putBoolean(BUNDLE_KEY_SHOW_COLOR_PALETTE, mView.isColorPaletteVisible()); - - outState.putBoolean("EditEventView_timebuttonclicked", mView.mTimeSelectedWasStartTime); - outState.putBoolean(BUNDLE_KEY_DATE_BUTTON_CLICKED, mView.mDateSelectedWasStartDate); } @Override diff --git a/src/com/android/calendar/event/EditEventView.java b/src/com/android/calendar/event/EditEventView.java index 3d8f81ab9..a8c50f323 100644 --- a/src/com/android/calendar/event/EditEventView.java +++ b/src/com/android/calendar/event/EditEventView.java @@ -18,10 +18,11 @@ package com.android.calendar.event; import android.app.Activity; import android.app.AlertDialog; -import android.app.DialogFragment; +import android.app.DatePickerDialog; import android.app.FragmentManager; import android.app.ProgressDialog; import android.app.Service; +import android.app.TimePickerDialog; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; @@ -57,6 +58,7 @@ import android.widget.AutoCompleteTextView; import android.widget.Button; import android.widget.CheckBox; import android.widget.CompoundButton; +import android.widget.DatePicker; import android.widget.LinearLayout; import android.widget.MultiAutoCompleteTextView; import android.widget.RadioButton; @@ -66,6 +68,7 @@ import android.widget.ScrollView; import android.widget.Spinner; import android.widget.TextView; import android.widget.TextView.OnEditorActionListener; +import android.widget.TimePicker; import com.android.calendar.CalendarEventModel; import com.android.calendar.CalendarEventModel.Attendee; @@ -81,11 +84,6 @@ import com.android.calendar.recurrencepicker.RecurrencePickerDialog; import com.android.calendarcommon2.EventRecurrence; import com.android.common.Rfc822InputFilter; import com.android.common.Rfc822Validator; -import com.android.datetimepicker.date.DatePickerDialog; -import com.android.datetimepicker.date.DatePickerDialog.OnDateSetListener; -import com.android.datetimepicker.time.RadialPickerLayout; -import com.android.datetimepicker.time.TimePickerDialog; -import com.android.datetimepicker.time.TimePickerDialog.OnTimeSetListener; import com.android.ex.chips.AccountSpecifier; import com.android.ex.chips.BaseRecipientAdapter; import com.android.ex.chips.ChipsUtil; @@ -112,8 +110,6 @@ public class EditEventView implements View.OnClickListener, DialogInterface.OnCa private static final String GOOGLE_SECONDARY_CALENDAR = "calendar.google.com"; private static final String PERIOD_SPACE = ". "; - private static final String FRAG_TAG_DATE_PICKER = "datePickerDialogFragment"; - private static final String FRAG_TAG_TIME_PICKER = "timePickerDialogFragment"; private static final String FRAG_TAG_TIME_ZONE_PICKER = "timeZonePickerDialogFragment"; private static final String FRAG_TAG_RECUR_PICKER = "recurrencePickerDialogFragment"; private static StringBuilder mSB = new StringBuilder(50); @@ -126,8 +122,6 @@ public class EditEventView implements View.OnClickListener, DialogInterface.OnCa */ private static InputFilter[] sRecipientFilters = new InputFilter[]{new Rfc822InputFilter()}; public boolean mIsMultipane; - public boolean mTimeSelectedWasStartTime; - public boolean mDateSelectedWasStartDate; ArrayList mEditOnlyList = new ArrayList(); ArrayList mEditViewList = new ArrayList(); ArrayList mViewOnlyList = new ArrayList(); @@ -175,7 +169,7 @@ public class EditEventView implements View.OnClickListener, DialogInterface.OnCa private int[] mOriginalPadding = new int[4]; private ProgressDialog mLoadingCalendarsDialog; private AlertDialog mNoCalendarsDialog; - private DialogFragment mTimezoneDialog; + private Activity mActivity; private EditDoneRunnable mDone; private View mView; @@ -226,8 +220,7 @@ public class EditEventView implements View.OnClickListener, DialogInterface.OnCa private ArrayList mUnsupportedReminders = new ArrayList(); private String mRrule; - public EditEventView(Activity activity, View view, EditDoneRunnable done, - boolean timeSelectedWasStartTime, boolean dateSelectedWasStartDate) { + public EditEventView(Activity activity, View view, EditDoneRunnable done) { mActivity = activity; mView = view; @@ -377,28 +370,7 @@ public class EditEventView implements View.OnClickListener, DialogInterface.OnCa if (tzpd != null) { tzpd.setOnTimeZoneSetListener(this); } - TimePickerDialog tpd = (TimePickerDialog) fm.findFragmentByTag(FRAG_TAG_TIME_PICKER); - if (tpd != null) { - View v; - mTimeSelectedWasStartTime = timeSelectedWasStartTime; - if (timeSelectedWasStartTime) { - v = mStartTimeButton; - } else { - v = mEndTimeButton; - } - tpd.setOnTimeSetListener(new TimeListener(v)); - } - mDatePickerDialog = (DatePickerDialog) fm.findFragmentByTag(FRAG_TAG_DATE_PICKER); - if (mDatePickerDialog != null) { - View v; - mDateSelectedWasStartDate = dateSelectedWasStartDate; - if (dateSelectedWasStartDate) { - v = mStartDateButton; - } else { - v = mEndDateButton; - } - mDatePickerDialog.setOnDateSetListener(new DateListener(v)); - } + } /** @@ -1658,7 +1630,7 @@ public class EditEventView implements View.OnClickListener, DialogInterface.OnCa } /* This class is used to update the time buttons. */ - private class TimeListener implements OnTimeSetListener { + private class TimeListener implements TimePickerDialog.OnTimeSetListener { private View mView; public TimeListener(View view) { @@ -1666,7 +1638,7 @@ public class EditEventView implements View.OnClickListener, DialogInterface.OnCa } @Override - public void onTimeSet(RadialPickerLayout view, int hourOfDay, int minute) { + public void onTimeSet(TimePicker view, int hourOfDay, int minute) { // Cache the member variables locally to avoid inner class overhead. Time startTime = mStartTime; Time endTime = mEndTime; @@ -1726,36 +1698,28 @@ public class EditEventView implements View.OnClickListener, DialogInterface.OnCa TimePickerDialog dialog; if (v == mStartTimeButton) { - mTimeSelectedWasStartTime = true; - if (mStartTimePickerDialog == null) { - mStartTimePickerDialog = TimePickerDialog.newInstance(new TimeListener(v), - mTime.hour, mTime.minute, DateFormat.is24HourFormat(mActivity)); - } else { - mStartTimePickerDialog.setStartTime(mTime.hour, mTime.minute); + if (mStartTimePickerDialog != null) { + mStartTimePickerDialog.dismiss(); } + mStartTimePickerDialog = new TimePickerDialog(mActivity, new TimeListener(v), + mTime.hour, mTime.minute, DateFormat.is24HourFormat(mActivity)); dialog = mStartTimePickerDialog; } else { - mTimeSelectedWasStartTime = false; - if (mEndTimePickerDialog == null) { - mEndTimePickerDialog = TimePickerDialog.newInstance(new TimeListener(v), - mTime.hour, mTime.minute, DateFormat.is24HourFormat(mActivity)); - } else { - mEndTimePickerDialog.setStartTime(mTime.hour, mTime.minute); + if (mEndTimePickerDialog != null) { + mEndTimePickerDialog.dismiss(); } + mEndTimePickerDialog = new TimePickerDialog(mActivity, new TimeListener(v), + mTime.hour, mTime.minute, DateFormat.is24HourFormat(mActivity)); dialog = mEndTimePickerDialog; } - final FragmentManager fm = mActivity.getFragmentManager(); - fm.executePendingTransactions(); + dialog.show(); - if (dialog != null && !dialog.isAdded()) { - dialog.show(fm, FRAG_TAG_TIME_PICKER); - } } } - private class DateListener implements OnDateSetListener { + private class DateListener implements DatePickerDialog.OnDateSetListener { View mView; public DateListener(View view) { @@ -1763,7 +1727,7 @@ public class EditEventView implements View.OnClickListener, DialogInterface.OnCa } @Override - public void onDateSet(DatePickerDialog view, int year, int month, int monthDay) { + public void onDateSet(DatePicker view, int year, int month, int monthDay) { Log.d(TAG, "onDateSet: " + year + " " + month + " " + monthDay); // Cache the member variables locally to avoid inner class overhead. Time startTime = mStartTime; @@ -1831,21 +1795,14 @@ public class EditEventView implements View.OnClickListener, DialogInterface.OnCa @Override public void onClick(View v) { - if (v == mStartDateButton) { - mDateSelectedWasStartDate = true; - } else { - mDateSelectedWasStartDate = false; - } final DateListener listener = new DateListener(v); if (mDatePickerDialog != null) { mDatePickerDialog.dismiss(); } - mDatePickerDialog = DatePickerDialog.newInstance(listener, + mDatePickerDialog = new DatePickerDialog(mActivity, listener, mTime.year, mTime.month, mTime.monthDay); - mDatePickerDialog.setFirstDayOfWeek(Utils.getFirstDayOfWeekAsCalendar(mActivity)); - mDatePickerDialog.setYearRange(Utils.YEAR_MIN, Utils.YEAR_MAX); - mDatePickerDialog.show(mActivity.getFragmentManager(), FRAG_TAG_DATE_PICKER); + mDatePickerDialog.show(); } } } diff --git a/src/com/android/calendar/recurrencepicker/RecurrencePickerDialog.java b/src/com/android/calendar/recurrencepicker/RecurrencePickerDialog.java index 6bb23a02c..f13d7563f 100644 --- a/src/com/android/calendar/recurrencepicker/RecurrencePickerDialog.java +++ b/src/com/android/calendar/recurrencepicker/RecurrencePickerDialog.java @@ -17,6 +17,7 @@ package com.android.calendar.recurrencepicker; import android.app.Activity; +import android.app.DatePickerDialog; import android.app.DialogFragment; import android.content.Context; import android.content.res.Configuration; @@ -43,6 +44,7 @@ import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.CompoundButton; import android.widget.CompoundButton.OnCheckedChangeListener; +import android.widget.DatePicker; import android.widget.EditText; import android.widget.LinearLayout; import android.widget.RadioButton; @@ -56,7 +58,7 @@ import android.widget.ToggleButton; import com.android.calendar.Utils; import com.android.calendarcommon2.EventRecurrence; -import com.android.datetimepicker.date.DatePickerDialog; + import java.text.DateFormatSymbols; import java.util.ArrayList; @@ -89,7 +91,7 @@ public class RecurrencePickerDialog extends DialogFragment implements OnItemSele }; private static final String BUNDLE_MODEL = "bundle_model"; private static final String BUNDLE_END_COUNT_HAS_FOCUS = "bundle_end_count_has_focus"; - private static final String FRAG_TAG_DATE_PICKER = "tag_date_picker_frag"; + private final int[] TIME_DAY_TO_CALENDAR_DAY = new int[] { Calendar.SUNDAY, Calendar.MONDAY, @@ -882,7 +884,7 @@ public class RecurrencePickerDialog extends DialogFragment implements OnItemSele } @Override - public void onDateSet(DatePickerDialog view, int year, int monthOfYear, int dayOfMonth) { + public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) { if (mModel.endDate == null) { mModel.endDate = new Time(mTime.timezone); mModel.endDate.hour = mModel.endDate.minute = mModel.endDate.second = 0; @@ -929,11 +931,9 @@ public class RecurrencePickerDialog extends DialogFragment implements OnItemSele if (mDatePickerDialog != null) { mDatePickerDialog.dismiss(); } - mDatePickerDialog = DatePickerDialog.newInstance(this, mModel.endDate.year, - mModel.endDate.month, mModel.endDate.monthDay); - mDatePickerDialog.setFirstDayOfWeek(Utils.getFirstDayOfWeekAsCalendar(getActivity())); - mDatePickerDialog.setYearRange(Utils.YEAR_MIN, Utils.YEAR_MAX); - mDatePickerDialog.show(getFragmentManager(), FRAG_TAG_DATE_PICKER); + mDatePickerDialog = new DatePickerDialog(getActivity(), this, + mModel.endDate.year, mModel.endDate.month, mModel.endDate.monthDay); + mDatePickerDialog.show(); } else if (mDone == v) { String rrule; if (mModel.recurrenceState == RecurrenceModel.STATE_NO_RECURRENCE) { @@ -950,11 +950,6 @@ public class RecurrencePickerDialog extends DialogFragment implements OnItemSele @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); - mDatePickerDialog = (DatePickerDialog) getFragmentManager() - .findFragmentByTag(FRAG_TAG_DATE_PICKER); - if (mDatePickerDialog != null) { - mDatePickerDialog.setOnDateSetListener(this); - } } public void setOnRecurrenceSetListener(OnRecurrenceSetListener l) { -- GitLab From 597699066df4a654083190551b0c24d31658331f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sun, 17 Nov 2019 14:12:34 +0100 Subject: [PATCH 52/95] update gradle, use appId suffix for debug to be able to install alongside release --- build.gradle | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/build.gradle b/build.gradle index d25f00405..bf54a8b25 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,7 @@ buildscript { repositories { - jcenter() google() + jcenter() } dependencies { @@ -11,13 +11,13 @@ buildscript { allprojects { repositories { - jcenter() google() + jcenter() } } project(':external:calendar') { - apply plugin: 'android-library' + apply plugin: 'com.android.library' android { compileSdkVersion 29 @@ -48,7 +48,7 @@ project(':external:calendar') { } project(':external:colorpicker') { - apply plugin: 'android-library' + apply plugin: 'com.android.library' android { compileSdkVersion 29 @@ -78,7 +78,7 @@ project(':external:colorpicker') { } project(':external:timezonepicker') { - apply plugin: 'android-library' + apply plugin: 'com.android.library' dependencies { implementation 'androidx.legacy:legacy-support-v4:1.0.0' @@ -111,7 +111,7 @@ project(':external:timezonepicker') { } project(':external:chips') { - apply plugin: 'android-library' + apply plugin: 'com.android.library' android { compileSdkVersion 29 @@ -175,6 +175,19 @@ android { } } + buildTypes { + release { + // TODO: could be enabled for ProGuard minimization + minifyEnabled false + } + + debug { + minifyEnabled false + + applicationIdSuffix ".debug" + } + } + /* * To sign release build, create file gradle.properties in ~/.gradle/ with this content: * -- GitLab From 4aea4c9850074b6f501c5ab7937e481b8f59b591 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Mon, 2 Dec 2019 22:31:01 +0100 Subject: [PATCH 53/95] Rework preferences using AndroidX and add offline calendars --- AndroidManifest.xml | 5 + build.gradle | 9 +- external/external.iml | 7 + res/drawable/circle.xml | 10 + res/drawable/circle_outline.xml | 10 + res/drawable/sync_off.xml | 10 + res/layout/add_offline_calendar_dialog.xml | 19 + res/values/strings.xml | 28 + .../general_preferences_nougat_and_less.xml | 144 +++++ res/xml/general_preferences_oreo_and_up.xml | 171 +++--- .../android/calendar/AllInOneActivity.java | 4 +- .../android/calendar/AsyncQueryService.java | 24 +- .../calendar/AsyncQueryServiceHelper.java | 4 +- .../android/calendar/CalendarController.java | 3 +- src/com/android/calendar/Utils.java | 5 +- .../android/calendar/persistence/Calendar.kt | 29 + .../persistence/CalendarRepository.kt | 171 ++++++ .../persistence/ContentProviderLiveData.kt | 61 +++ .../calendar/settings/AboutPreferences.kt | 48 ++ .../AddOfflineCalendarDialogFragment.kt | 63 +++ .../settings/CalendarColorPickerDialogX.kt | 302 +++++++++++ .../calendar/settings/CalendarDataStore.kt | 111 ++++ .../calendar/settings/CalendarPreferences.kt | 203 +++++++ .../calendar/settings/ColorPickerDialogX.java | 198 +++++++ .../calendar/settings/GeneralPreferences.kt | 509 ++++++++++++++++++ .../calendar/settings/MainListPreferences.kt | 209 +++++++ .../calendar/settings/MainListViewModel.kt | 49 ++ .../settings/MainListViewModelFactory.kt | 35 ++ .../settings/QuickResponsePreferences.kt | 80 +++ .../calendar/settings/SettingsActivity.kt | 99 ++++ .../settings/TimeZonePickerDialogX.java | 116 ++++ .../settings/ViewDetailsPreferences.kt | 169 ++++++ 32 files changed, 2804 insertions(+), 101 deletions(-) create mode 100644 res/drawable/circle.xml create mode 100644 res/drawable/circle_outline.xml create mode 100644 res/drawable/sync_off.xml create mode 100644 res/layout/add_offline_calendar_dialog.xml create mode 100644 res/xml/general_preferences_nougat_and_less.xml create mode 100644 src/com/android/calendar/persistence/Calendar.kt create mode 100644 src/com/android/calendar/persistence/CalendarRepository.kt create mode 100644 src/com/android/calendar/persistence/ContentProviderLiveData.kt create mode 100644 src/com/android/calendar/settings/AboutPreferences.kt create mode 100644 src/com/android/calendar/settings/AddOfflineCalendarDialogFragment.kt create mode 100644 src/com/android/calendar/settings/CalendarColorPickerDialogX.kt create mode 100644 src/com/android/calendar/settings/CalendarDataStore.kt create mode 100644 src/com/android/calendar/settings/CalendarPreferences.kt create mode 100644 src/com/android/calendar/settings/ColorPickerDialogX.java create mode 100644 src/com/android/calendar/settings/GeneralPreferences.kt create mode 100644 src/com/android/calendar/settings/MainListPreferences.kt create mode 100644 src/com/android/calendar/settings/MainListViewModel.kt create mode 100644 src/com/android/calendar/settings/MainListViewModelFactory.kt create mode 100644 src/com/android/calendar/settings/QuickResponsePreferences.kt create mode 100644 src/com/android/calendar/settings/SettingsActivity.kt create mode 100644 src/com/android/calendar/settings/TimeZonePickerDialogX.java create mode 100644 src/com/android/calendar/settings/ViewDetailsPreferences.kt diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 07d3d11de..0f8e2d0ae 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -154,6 +154,11 @@ android:label="@string/preferences_title" android:parentActivityName="com.android.calendar.AllInOneActivity" /> + + + + + + diff --git a/res/drawable/circle.xml b/res/drawable/circle.xml new file mode 100644 index 000000000..2af16fdf4 --- /dev/null +++ b/res/drawable/circle.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/res/drawable/circle_outline.xml b/res/drawable/circle_outline.xml new file mode 100644 index 000000000..e90297236 --- /dev/null +++ b/res/drawable/circle_outline.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/res/drawable/sync_off.xml b/res/drawable/sync_off.xml new file mode 100644 index 000000000..d677bc209 --- /dev/null +++ b/res/drawable/sync_off.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/res/layout/add_offline_calendar_dialog.xml b/res/layout/add_offline_calendar_dialog.xml new file mode 100644 index 000000000..474842811 --- /dev/null +++ b/res/layout/add_offline_calendar_dialog.xml @@ -0,0 +1,19 @@ + + + + + + + + + diff --git a/res/values/strings.xml b/res/values/strings.xml index 7fa2255b1..f8284db5f 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -851,4 +851,32 @@ Start and end time Start and end time below the event + + %1$s account + Delete calendar + Change name + Account type + Color + Display events + Synchronize this calendar + Not synchronized + Events are not displayed + General settings + About Etar + Add remote calendar (CalDAV) + Add offline calendar + Add offline calendar + Offline calendars are NOT synchronized to a cloud service and only available on your phone. + Add calendar + Name + Cancel + Warning + Changing the color may be reverted when the calendar is synchronized again.\n\nIn DAVx⁵ \'Manage calendar colors\' can be disabled to prevent this. + I understand + Do you really want to delete this calendar? + Delete calendar + Cancel + + Offline Calendar + diff --git a/res/xml/general_preferences_nougat_and_less.xml b/res/xml/general_preferences_nougat_and_less.xml new file mode 100644 index 000000000..edeecb192 --- /dev/null +++ b/res/xml/general_preferences_nougat_and_less.xml @@ -0,0 +1,144 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/xml/general_preferences_oreo_and_up.xml b/res/xml/general_preferences_oreo_and_up.xml index 40a078229..b7bb5c084 100644 --- a/res/xml/general_preferences_oreo_and_up.xml +++ b/res/xml/general_preferences_oreo_and_up.xml @@ -14,114 +14,115 @@ limitations under the License. --> - - + + + app:key="pref_theme" + app:title="@string/preferences_theme" + app:entries="@array/pref_theme_entries" + app:entryValues="@array/pref_theme_values" + app:defaultValue="light"/> + app:key="pref_color" + app:title="@string/preferences_color" + app:entries="@array/pref_color_entries" + app:entryValues="@array/pref_color_values" + app:defaultValue="teal"/> - + app:key="preferences_default_start" + app:defaultValue="-2" + app:title="@string/default_start_title" + app:entries="@array/default_start_entries" + app:entryValues="@array/default_start_values" /> + + app:key="preferences_hide_declined" + app:defaultValue="false" + app:title="@string/preferences_hide_declined_title" /> + app:key="preferences_show_week_num" + app:defaultValue="false" + app:title="@string/preferences_show_week_num_title" /> + app:key="preferences_week_start_day" + app:defaultValue="@string/preferences_week_start_day_default" + app:title="@string/preferences_week_start_day_title" + app:entries="@array/preferences_week_start_day_labels" + app:entryValues="@array/preferences_week_start_day_values" + app:dialogTitle="@string/preferences_week_start_day_dialog" /> + app:key="preferences_days_per_week" + app:defaultValue="@string/preferences_days_per_week_default" + app:title="@string/preferences_days_per_week_title" + app:entries="@array/preferences_days_per_week_labels" + app:entryValues="@array/preferences_days_per_week_values" + app:dialogTitle="@string/preferences_days_per_week_dialog" /> + app:key="preferences_home_tz_enabled" + app:defaultValue="false" + app:title="@string/preferences_use_home_tz_title" + app:summary="@string/preferences_use_home_tz_descrip" /> + - + app:key="preferences_clear_search_history" + app:title="@string/preferences_clear_search_history_title" + app:summary="@string/preferences_clear_search_history_summary" /> + app:key="preferences_alerts_category" + app:title="@string/preferences_reminder_title"> + app:key="preferences_notification" + app:title="@string/preferences_alerts_title" /> + app:key="preferences_alerts_popup" + app:layout="?android:attr/preferenceLayoutChild" + app:defaultValue="false" + app:title="@string/preferences_alerts_popup_title" /> + app:key="preferences_custom_snooze_delay" + app:defaultValue="false" + app:title="@string/preferences_alerts_custom_snooze_delay_title" + app:summaryOn="@string/preferences_alerts_custom_snooze_delay_summary_on" + app:summaryOff="@string/preferences_alerts_custom_snooze_delay_summary_off" /> + app:key="preferences_default_snooze_delay" + app:defaultValue="@string/preferences_default_snooze_delay_default" + app:entryValues="@array/preferences_default_snooze_delay_values" + app:title="@string/preferences_default_snooze_delay_title" + app:dialogTitle="@string/preferences_default_snooze_delay_dialog" /> + app:key="preferences_default_reminder" + app:defaultValue="@string/preferences_default_reminder_default" + app:title="@string/preferences_default_reminder_title" + app:entries="@array/preferences_default_reminder_labels" + app:entryValues="@array/preferences_default_reminder_values" + app:dialogTitle="@string/preferences_default_reminder_dialog" /> - + diff --git a/src/com/android/calendar/AllInOneActivity.java b/src/com/android/calendar/AllInOneActivity.java index 0e2de036b..fa3ac62f2 100644 --- a/src/com/android/calendar/AllInOneActivity.java +++ b/src/com/android/calendar/AllInOneActivity.java @@ -45,6 +45,8 @@ import android.preference.PreferenceActivity; import android.provider.CalendarContract; import android.provider.CalendarContract.Attendees; import android.provider.CalendarContract.Events; + +import com.android.calendar.settings.SettingsActivity; import com.google.android.material.floatingactionbutton.FloatingActionButton; import com.google.android.material.navigation.NavigationView; import androidx.core.app.ActivityCompat; @@ -910,7 +912,7 @@ public class AllInOneActivity extends AbstractCalendarActivity implements EventH } else if (itemId == R.id.action_import) { ImportActivity.pickImportFile(this); } else if (itemId == R.id.action_view_settings) { - Intent intent = new Intent(this, CalendarSettingsActivity.class); + Intent intent = new Intent(this, SettingsActivity.class); intent.putExtra(PreferenceActivity.EXTRA_SHOW_FRAGMENT, ViewDetailsPreferences.class.getName()); intent.putExtra( PreferenceActivity.EXTRA_NO_HEADERS, true ); startActivity(intent); diff --git a/src/com/android/calendar/AsyncQueryService.java b/src/com/android/calendar/AsyncQueryService.java index fd2d187f7..9b8e3e0bb 100644 --- a/src/com/android/calendar/AsyncQueryService.java +++ b/src/com/android/calendar/AsyncQueryService.java @@ -27,6 +27,8 @@ import android.os.Handler; import android.os.Message; import android.util.Log; +import androidx.annotation.Nullable; + import com.android.calendar.AsyncQueryServiceHelper.OperationInfo; import java.util.ArrayList; @@ -109,8 +111,8 @@ public class AsyncQueryService extends Handler { * (excluding the ORDER BY itself). Passing null will use the * default sort order, which may be unordered. */ - public void startQuery(int token, Object cookie, Uri uri, String[] projection, - String selection, String[] selectionArgs, String orderBy) { + public void startQuery(int token, @Nullable Object cookie, Uri uri, String[] projection, + String selection, String[] selectionArgs, String orderBy) { OperationInfo info = new OperationInfo(); info.op = Operation.EVENT_ARG_QUERY; info.resolver = mContext.getContentResolver(); @@ -141,7 +143,7 @@ public class AsyncQueryService extends Handler { * execute before the delayed time when another operation is * added. Useful for implementing single level undo. */ - public void startInsert(int token, Object cookie, Uri uri, ContentValues initialValues, + public void startInsert(int token, @Nullable Object cookie, Uri uri, ContentValues initialValues, long delayMillis) { OperationInfo info = new OperationInfo(); info.op = Operation.EVENT_ARG_INSERT; @@ -177,7 +179,7 @@ public class AsyncQueryService extends Handler { * execute before the delayed time when another operation is * added. Useful for implementing single level undo. */ - public void startUpdate(int token, Object cookie, Uri uri, ContentValues values, + public void startUpdate(int token, @Nullable Object cookie, Uri uri, ContentValues values, String selection, String[] selectionArgs, long delayMillis) { OperationInfo info = new OperationInfo(); info.op = Operation.EVENT_ARG_UPDATE; @@ -214,7 +216,7 @@ public class AsyncQueryService extends Handler { * execute before the delayed time when another operation is * added. Useful for implementing single level undo. */ - public void startDelete(int token, Object cookie, Uri uri, String selection, + public void startDelete(int token, @Nullable Object cookie, Uri uri, String selection, String[] selectionArgs, long delayMillis) { OperationInfo info = new OperationInfo(); info.op = Operation.EVENT_ARG_DELETE; @@ -245,7 +247,7 @@ public class AsyncQueryService extends Handler { * execute before the delayed time when another operation is * added. Useful for implementing single level undo. */ - public void startBatch(int token, Object cookie, String authority, + public void startBatch(int token, @Nullable Object cookie, String authority, ArrayList cpo, long delayMillis) { OperationInfo info = new OperationInfo(); info.op = Operation.EVENT_ARG_BATCH; @@ -269,7 +271,7 @@ public class AsyncQueryService extends Handler { * @param cookie the cookie object passed in from {@link #startQuery}. * @param cursor The cursor holding the results from the query. */ - protected void onQueryComplete(int token, Object cookie, Cursor cursor) { + protected void onQueryComplete(int token, @Nullable Object cookie, Cursor cursor) { if (localLOGV) { Log.d(TAG, "########## default onQueryComplete"); } @@ -284,7 +286,7 @@ public class AsyncQueryService extends Handler { * {@link #startInsert}. * @param uri the uri returned from the insert operation. */ - protected void onInsertComplete(int token, Object cookie, Uri uri) { + protected void onInsertComplete(int token, @Nullable Object cookie, Uri uri) { if (localLOGV) { Log.d(TAG, "########## default onInsertComplete"); } @@ -299,7 +301,7 @@ public class AsyncQueryService extends Handler { * {@link #startUpdate}. * @param result the result returned from the update operation */ - protected void onUpdateComplete(int token, Object cookie, int result) { + protected void onUpdateComplete(int token, @Nullable Object cookie, int result) { if (localLOGV) { Log.d(TAG, "########## default onUpdateComplete"); } @@ -314,7 +316,7 @@ public class AsyncQueryService extends Handler { * {@link #startDelete}. * @param result the result returned from the delete operation */ - protected void onDeleteComplete(int token, Object cookie, int result) { + protected void onDeleteComplete(int token, @Nullable Object cookie, int result) { if (localLOGV) { Log.d(TAG, "########## default onDeleteComplete"); } @@ -331,7 +333,7 @@ public class AsyncQueryService extends Handler { * @param results the result returned from executing the * {@link ContentProviderOperation} */ - protected void onBatchComplete(int token, Object cookie, ContentProviderResult[] results) { + protected void onBatchComplete(int token, @Nullable Object cookie, ContentProviderResult[] results) { if (localLOGV) { Log.d(TAG, "########## default onBatchComplete"); } diff --git a/src/com/android/calendar/AsyncQueryServiceHelper.java b/src/com/android/calendar/AsyncQueryServiceHelper.java index 449d329ce..5ec180a80 100644 --- a/src/com/android/calendar/AsyncQueryServiceHelper.java +++ b/src/com/android/calendar/AsyncQueryServiceHelper.java @@ -31,6 +31,8 @@ import android.os.RemoteException; import android.os.SystemClock; import android.util.Log; +import androidx.annotation.Nullable; + import com.android.calendar.AsyncQueryService.Operation; import java.util.ArrayList; @@ -286,7 +288,7 @@ public class AsyncQueryServiceHelper extends IntentService { public String[] selectionArgs; public String orderBy; public Object result; - public Object cookie; + @Nullable public Object cookie; public ContentValues values; public ArrayList cpo; diff --git a/src/com/android/calendar/CalendarController.java b/src/com/android/calendar/CalendarController.java index 93786f8bf..234885071 100644 --- a/src/com/android/calendar/CalendarController.java +++ b/src/com/android/calendar/CalendarController.java @@ -37,6 +37,7 @@ import android.util.Pair; import com.android.calendar.event.EditEventActivity; import com.android.calendar.selectcalendars.SelectVisibleCalendarsActivity; +import com.android.calendar.settings.SettingsActivity; import java.lang.ref.WeakReference; import java.util.Iterator; @@ -564,7 +565,7 @@ public class CalendarController { private void launchSettings() { Intent intent = new Intent(Intent.ACTION_VIEW); - intent.setClass(mContext, CalendarSettingsActivity.class); + intent.setClass(mContext, SettingsActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_SINGLE_TOP); mContext.startActivity(intent); } diff --git a/src/com/android/calendar/Utils.java b/src/com/android/calendar/Utils.java index c16ab6faa..11052c170 100644 --- a/src/com/android/calendar/Utils.java +++ b/src/com/android/calendar/Utils.java @@ -37,6 +37,8 @@ import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.provider.CalendarContract.Calendars; + +import androidx.annotation.NonNull; import androidx.appcompat.widget.SearchView; import android.text.Spannable; import android.text.SpannableString; @@ -110,7 +112,7 @@ public class Utils { // historical // reasons, as it's what PreferenceManager assigned the first time the file // was created. - static final String SHARED_PREFS_NAME = "com.android.calendar_preferences"; + public static final String SHARED_PREFS_NAME = "com.android.calendar_preferences"; static final String MACHINE_GENERATED_ADDRESS = "calendar.google.com"; private static final boolean DEBUG = false; private static final String TAG = "CalUtils"; @@ -1641,6 +1643,7 @@ public class Utils { * @param context * @return a list of quick responses. */ + @NonNull public static String[] getQuickResponses(Context context) { String[] s = Utils.getSharedPreference(context, KEY_QUICK_RESPONSES, (String[]) null); diff --git a/src/com/android/calendar/persistence/Calendar.kt b/src/com/android/calendar/persistence/Calendar.kt new file mode 100644 index 000000000..9301ede31 --- /dev/null +++ b/src/com/android/calendar/persistence/Calendar.kt @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2020 Dominik Schürmann + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.android.calendar.persistence + + +data class Calendar(val id: Long, + val accountName: String, + val accountType: String, + val name: String, + val displayName: String, + val color: Int, + val visible: Boolean, + val syncEvents: Boolean, + val isPrimary: Boolean) diff --git a/src/com/android/calendar/persistence/CalendarRepository.kt b/src/com/android/calendar/persistence/CalendarRepository.kt new file mode 100644 index 000000000..0ccecdfff --- /dev/null +++ b/src/com/android/calendar/persistence/CalendarRepository.kt @@ -0,0 +1,171 @@ +/* + * Copyright (C) 2020 Dominik Schürmann + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.android.calendar.persistence + +import android.accounts.Account +import android.annotation.SuppressLint +import android.app.Application +import android.content.ContentUris +import android.content.ContentValues +import android.content.Context +import android.net.Uri +import android.provider.CalendarContract +import androidx.lifecycle.LiveData + +/** + * Repository as in + * https://developer.android.com/jetpack/docs/guide#recommended-app-arch + * + * TODO: + * Replace usages of AsyncQueryService in Etar with repositories + * Currently CalendarRepository is only used for settings + */ +@SuppressLint("MissingPermission") +internal class CalendarRepository(val application: Application) { + + private var contentResolver = application.contentResolver + + private var allCalendars: CalendarLiveData + + init { + allCalendars = CalendarLiveData(application.applicationContext) + } + + fun getCalendarsOrderedByAccount(): LiveData> { + return allCalendars + } + + class CalendarLiveData(val context: Context) : ContentProviderLiveData>(context, uri) { + + override fun getContentProviderValue(): List { + val calendars: MutableList = mutableListOf() + + context.contentResolver.query(uri, PROJECTION, null, null, CalendarContract.Calendars.ACCOUNT_NAME)?.use { + while (it.moveToNext()) { + val id = it.getLong(PROJECTION_INDEX_ID) + val accountName = it.getString(PROJECTION_INDEX_ACCOUNT_NAME) + val accountType = it.getString(PROJECTION_INDEX_ACCOUNT_TYPE) + val name = it.getString(PROJECTION_INDEX_NAME) + val calName = it.getString(PROJECTION_INDEX_CALENDAR_DISPLAY_NAME) + val color = it.getInt(PROJECTION_INDEX_CALENDAR_COLOR) + val visible = it.getInt(PROJECTION_INDEX_VISIBLE) == 1 + val syncEvents = it.getInt(PROJECTION_INDEX_SYNC_EVENTS) == 1 + val isPrimary = it.getInt(PROJECTION_INDEX_IS_PRIMARY) == 1 + + calendars.add(Calendar(id, accountName, accountType, name, calName, color, visible, syncEvents, isPrimary)) + } + } + return calendars + } + + companion object { + private val uri = CalendarContract.Calendars.CONTENT_URI + + private const val IS_PRIMARY = "primary" + + private val PROJECTION = arrayOf( + CalendarContract.Calendars._ID, + CalendarContract.Calendars.ACCOUNT_NAME, + CalendarContract.Calendars.ACCOUNT_TYPE, + CalendarContract.Calendars.OWNER_ACCOUNT, + CalendarContract.Calendars.NAME, + CalendarContract.Calendars.CALENDAR_DISPLAY_NAME, + CalendarContract.Calendars.CALENDAR_COLOR, + CalendarContract.Calendars.VISIBLE, + CalendarContract.Calendars.SYNC_EVENTS, + "(" + CalendarContract.Calendars.ACCOUNT_NAME + "=" + CalendarContract.Calendars.OWNER_ACCOUNT + ") " + + "AS \"" + IS_PRIMARY + "\"" + ) + const val PROJECTION_INDEX_ID = 0 + const val PROJECTION_INDEX_ACCOUNT_NAME = 1 + const val PROJECTION_INDEX_ACCOUNT_TYPE = 2 + const val PROJECTION_INDEX_OWNER_ACCOUNT = 3 + const val PROJECTION_INDEX_NAME = 4 + const val PROJECTION_INDEX_CALENDAR_DISPLAY_NAME = 5 + const val PROJECTION_INDEX_CALENDAR_COLOR = 6 + const val PROJECTION_INDEX_VISIBLE = 7 + const val PROJECTION_INDEX_SYNC_EVENTS = 8 + const val PROJECTION_INDEX_IS_PRIMARY = 9 + } + } + + /** + * Operations only work if they are made "under" the correct account name + */ + private fun buildLocalCalendarUri(accountName: String): Uri { + return CalendarContract.Calendars.CONTENT_URI.buildUpon() + .appendQueryParameter(CalendarContract.CALLER_IS_SYNCADAPTER, "true") + .appendQueryParameter(CalendarContract.Calendars.ACCOUNT_NAME, accountName) + .appendQueryParameter(CalendarContract.Calendars.ACCOUNT_TYPE, CalendarContract.ACCOUNT_TYPE_LOCAL).build() + } + + private fun buildLocalCalendarContentValues(accountName: String, displayName: String, color: Int): ContentValues { + val uniqueName = "etar_local_" + displayName + "_" + System.currentTimeMillis() + return ContentValues().apply { + put(CalendarContract.Calendars.ACCOUNT_NAME, accountName) + put(CalendarContract.Calendars.ACCOUNT_TYPE, CalendarContract.ACCOUNT_TYPE_LOCAL) + put(CalendarContract.Calendars.NAME, uniqueName) + put(CalendarContract.Calendars.CALENDAR_DISPLAY_NAME, displayName) + put(CalendarContract.Calendars.CALENDAR_COLOR, color) + put(CalendarContract.Calendars.CALENDAR_ACCESS_LEVEL, CalendarContract.Calendars.CAL_ACCESS_OWNER) +// put(CalendarContract.Calendars.OWNER_ACCOUNT, accountName) // primary calendar for this account + put(CalendarContract.Calendars.OWNER_ACCOUNT, "") // non-primary + put(CalendarContract.Calendars.VISIBLE, 1) + put(CalendarContract.Calendars.SYNC_EVENTS, 1) + } + } + + /** + * Add calendar with given name and color + */ + fun addLocalCalendar(accountName: String, displayName: String, color: Int): Uri { + val cv = buildLocalCalendarContentValues(accountName, displayName, color) + return contentResolver.insert(buildLocalCalendarUri(accountName), cv) + ?: throw IllegalArgumentException() + } + + /** + * @return true iff exactly one row is deleted + */ + fun deleteLocalCalendar(accountName: String, id: Long): Boolean { + val calUri = ContentUris.withAppendedId(buildLocalCalendarUri(accountName), id) + return contentResolver.delete(calUri, null, null) == 1 + } + + fun queryAccount(calendarId: Long): Account? { + val calendarUri = ContentUris.withAppendedId(CalendarContract.Calendars.CONTENT_URI, calendarId) + contentResolver.query(calendarUri, ACCOUNT_PROJECTION, null, null, null)?.use { + if (it.moveToFirst()) { + val accountName = it.getString(ACCOUNT_INDEX_NAME) + val accountType = it.getString(ACCOUNT_INDEX_TYPE) + return Account(accountName, accountType) + } + } + return null + } + + companion object { + private val ACCOUNT_PROJECTION = arrayOf( + CalendarContract.Calendars.ACCOUNT_NAME, + CalendarContract.Calendars.ACCOUNT_TYPE + ) + const val ACCOUNT_INDEX_NAME = 0 + const val ACCOUNT_INDEX_TYPE = 1 + } + +} \ No newline at end of file diff --git a/src/com/android/calendar/persistence/ContentProviderLiveData.kt b/src/com/android/calendar/persistence/ContentProviderLiveData.kt new file mode 100644 index 000000000..3c3f10914 --- /dev/null +++ b/src/com/android/calendar/persistence/ContentProviderLiveData.kt @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2020 Dominik Schürmann + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.android.calendar.persistence + +import android.content.Context +import android.database.ContentObserver +import android.net.Uri +import androidx.lifecycle.MutableLiveData + +/** + * From https://medium.com/@jmcassis/android-livedata-and-content-provider-updates-5f8fd3b2b3a4 + * Added postValue(getContentProviderValue()) in onActive() + * + * Abstract [LiveData] to observe Android's Content Provider changes. + * Provide a [uri] to observe changes and implement [getContentProviderValue] + * to provide data to post when content provider notifies a change. + */ +abstract class ContentProviderLiveData( + private val context: Context, + private val uri: Uri +) : MutableLiveData() { + private lateinit var observer: ContentObserver + + override fun onActive() { + observer = object : ContentObserver(null) { + override fun onChange(self: Boolean) { + // Notify LiveData listeners an event has happened + postValue(getContentProviderValue()) + } + } + context.contentResolver.registerContentObserver(uri, true, observer) + + // post value when this LiveData is observed on first time + postValue(getContentProviderValue()) + } + + override fun onInactive() { + context.contentResolver.unregisterContentObserver(observer) + } + + /** + * Implement if you need to provide [T] value to be posted + * when observed content is changed. + */ + abstract fun getContentProviderValue(): T +} \ No newline at end of file diff --git a/src/com/android/calendar/settings/AboutPreferences.kt b/src/com/android/calendar/settings/AboutPreferences.kt new file mode 100644 index 000000000..6b10f4451 --- /dev/null +++ b/src/com/android/calendar/settings/AboutPreferences.kt @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2020 Dominik Schürmann + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.android.calendar.settings + +import android.content.pm.PackageManager.NameNotFoundException +import android.os.Bundle +import androidx.preference.Preference +import androidx.preference.PreferenceFragmentCompat +import ws.xsoh.etar.R + +class AboutPreferences : PreferenceFragmentCompat() { + + override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { + setPreferencesFromResource(R.xml.about_preferences, rootKey) + setVersion() + } + + private fun setVersion() { + val activity = activity!! + val versionPreference = findPreference(KEY_BUILD_VERSION)!! + + try { + val packageInfo = activity.packageManager.getPackageInfo(activity.packageName, 0) + versionPreference.summary = packageInfo.versionName + } catch (e: NameNotFoundException) { + versionPreference.summary = "?" + } + } + + companion object { + private const val KEY_BUILD_VERSION = "build_version" + } +} \ No newline at end of file diff --git a/src/com/android/calendar/settings/AddOfflineCalendarDialogFragment.kt b/src/com/android/calendar/settings/AddOfflineCalendarDialogFragment.kt new file mode 100644 index 000000000..c87536e86 --- /dev/null +++ b/src/com/android/calendar/settings/AddOfflineCalendarDialogFragment.kt @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2020 Dominik Schürmann + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.android.calendar.settings + +import android.annotation.SuppressLint +import android.app.Dialog +import android.os.Bundle +import android.widget.EditText +import androidx.appcompat.app.AlertDialog +import androidx.fragment.app.DialogFragment +import com.android.calendar.persistence.CalendarRepository +import ws.xsoh.etar.R + +class AddOfflineCalendarDialogFragment : DialogFragment() { + + private lateinit var nameEditText: EditText + + @SuppressLint("InflateParams") + override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { + return activity?.let { + val inflater = requireActivity().layoutInflater + val view = inflater.inflate(R.layout.add_offline_calendar_dialog, null) + nameEditText = view.findViewById(R.id.offline_calendar_name) + + val builder = AlertDialog.Builder(it).apply { + setView(view) + setTitle(R.string.preferences_list_add_offline_title) + setMessage(R.string.preferences_list_add_offline_message) + setPositiveButton(R.string.preferences_list_add_offline_button) { _, _ -> + addCalendar() + } + setNegativeButton(R.string.preferences_list_add_offline_cancel) { dialog, _ -> + dialog.cancel() + } + } + + builder.create() + } ?: throw IllegalStateException("Activity cannot be null") + } + + private fun addCalendar() { + val accountName = getString(R.string.offline_account_name) + val displayName = nameEditText.text.toString() + val color = -10308462 + val repository = CalendarRepository(activity!!.application) + repository.addLocalCalendar(accountName, displayName, color) + } +} diff --git a/src/com/android/calendar/settings/CalendarColorPickerDialogX.kt b/src/com/android/calendar/settings/CalendarColorPickerDialogX.kt new file mode 100644 index 000000000..6104c80b4 --- /dev/null +++ b/src/com/android/calendar/settings/CalendarColorPickerDialogX.kt @@ -0,0 +1,302 @@ +/* + * Copyright (C) 2019 Dominik Schürmann + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.android.calendar.settings + +import android.accounts.Account +import android.app.Dialog +import android.content.ContentUris +import android.content.ContentValues +import android.content.Context +import android.database.Cursor +import android.os.Bundle +import android.provider.CalendarContract.* +import android.util.SparseIntArray +import androidx.appcompat.app.AlertDialog +import com.android.calendar.AsyncQueryService +import com.android.calendar.Utils +import com.android.colorpicker.ColorPickerSwatch.OnColorSelectedListener +import com.android.colorpicker.HsvColorComparator +import ws.xsoh.etar.R +import java.util.* + + +/** + * Based on CalendarColorPickerDialog.java + * - extends ColorPickerDialogX for androidx compatibility + * - added OnCalendarColorSelectedListener + * - handle calendars where no additional colors are provided by the account + * - handle local accounts + */ +class CalendarColorPickerDialogX : ColorPickerDialogX() { + private var queryService: QueryService? = null + private val colorKeyMap = SparseIntArray() + private var calendarId: Long = 0 + private var isLocalAccount: Boolean = false + + private var calendarColorListener: OnCalendarColorSelectedListener? = null + + interface OnCalendarColorSelectedListener { + fun onColorSelected(color: Int) + } + + override fun onSaveInstanceState(outState: Bundle) { + super.onSaveInstanceState(outState) + outState.putLong(KEY_CALENDAR_ID, calendarId) + saveColorKeys(outState) + } + + private fun saveColorKeys(outState: Bundle) { + val colorKeys = IntArray(mColors.size) + for (i in mColors.indices) { + colorKeys[i] = colorKeyMap.get(mColors[i]) + } + outState.putIntArray(KEY_COLOR_KEYS, colorKeys) + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + if (savedInstanceState != null) { + calendarId = savedInstanceState.getLong(KEY_CALENDAR_ID) + retrieveColorKeys(savedInstanceState) + } + setOnColorSelectedListener(ThisOnColorSelectedListener()) + } + + private fun retrieveColorKeys(savedInstanceState: Bundle) { + val colorKeys = savedInstanceState.getIntArray(KEY_COLOR_KEYS) + if (mColors != null && colorKeys != null) { + for (i in mColors.indices) { + colorKeyMap.put(mColors[i], colorKeys[i]) + } + } + } + + override fun setColors(colors: IntArray) { + throw IllegalStateException("Must call setCalendarId() to update calendar colors") + } + + override fun setColors(colors: IntArray, selectedColor: Int) { + throw IllegalStateException("Must call setCalendarId() to update calendar colors") + } + + fun setCalendarId(calendarId: Long) { + if (calendarId != this.calendarId) { + this.calendarId = calendarId + startQuery() + } + } + + fun setCalendarColorListener(calendarColorListener: OnCalendarColorSelectedListener) { + this.calendarColorListener = calendarColorListener + } + + override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { + val dialog = super.onCreateDialog(savedInstanceState) + queryService = QueryService(activity!!) + if (mColors == null) { + startQuery() + } + return dialog + } + + private fun startQuery() { + if (queryService != null) { + showProgressBarView() + queryService!!.startCalendarQuery() + } + } + + private inner class QueryService(context: Context) : AsyncQueryService(context) { + + fun startCalendarQuery() { + startQuery(TOKEN_QUERY_CALENDARS, null, + ContentUris.withAppendedId(Calendars.CONTENT_URI, calendarId), + CALENDARS_PROJECTION, null, null, null) + } + + private fun startColorQuery(account: Account) { + val uri = Colors.CONTENT_URI + val args = arrayOf(account.name, account.type) + startQuery(TOKEN_QUERY_COLORS, null, uri, COLORS_PROJECTION, COLORS_WHERE, args, null) + } + + override fun onQueryComplete(token: Int, cookie: Any?, cursor: Cursor?) { + // If the query didn't return a cursor for some reason return + if (cursor == null) { + return + } + + // If the Activity is finishing, then close the cursor. + // Otherwise, use the new cursor in the adapter. + val activity = activity + if (activity == null || activity.isFinishing) { + cursor.close() + return + } + + when (token) { + TOKEN_QUERY_CALENDARS -> { + if (!cursor.moveToFirst()) { + cursor.close() + dismiss() + return + } + mSelectedColor = Utils.getDisplayColorFromColor(cursor.getInt(CALENDARS_INDEX_CALENDAR_COLOR)) + val account = Account(cursor.getString(CALENDARS_INDEX_ACCOUNT_NAME), + cursor.getString(CALENDARS_INDEX_ACCOUNT_TYPE)) + isLocalAccount = account.type == ACCOUNT_TYPE_LOCAL + + cursor.close() + + startColorQuery(account) + } + TOKEN_QUERY_COLORS -> { + if (!cursor.moveToFirst()) { + // no additional colors defined by account + cursor.close() + useDefaultColors() + return + } + useColorKeyMap(cursor) + cursor.close() + } + } + } + + } + + private fun useColorKeyMap(cursor: Cursor) { + colorKeyMap.clear() + val colors = ArrayList() + do { + val colorKey = cursor.getInt(COLORS_INDEX_COLOR_KEY) + val rawColor = cursor.getInt(COLORS_INDEX_COLOR) + val displayColor = Utils.getDisplayColorFromColor(rawColor) + colorKeyMap.put(displayColor, colorKey) + colors.add(displayColor) + } while (cursor.moveToNext()) + val colorsToSort = colors.toTypedArray() + setColorPalette(colorsToSort) + showPaletteView() + } + + private fun useDefaultColors() { + if (!isLocalAccount) { + val warningDialog = AlertDialog.Builder(activity!!) + .setTitle(R.string.preferences_calendar_color_warning_title) + .setMessage(R.string.preferences_calendar_color_warning_message) + .setPositiveButton(R.string.preferences_calendar_color_warning_button) { dialogInterface, _ -> + dialogInterface.dismiss() + } + .create() + warningDialog.show() + } + setColorPalette(defaultColors) + showPaletteView() + } + + private fun setColorPalette(colorsToSort: Array) { + Arrays.sort(colorsToSort, HsvColorComparator()) + mColors = IntArray(colorsToSort.size) + for (i in mColors.indices) { + mColors[i] = colorsToSort[i] + } + } + + private inner class ThisOnColorSelectedListener : OnColorSelectedListener { + + override fun onColorSelected(color: Int) { + if (color == mSelectedColor || queryService == null) { + return + } + + val values = ContentValues() + if (colorKeyMap.size() == 0) { + values.put(Calendars.CALENDAR_COLOR, color) + } else { + values.put(Calendars.CALENDAR_COLOR_KEY, colorKeyMap.get(color)) + } + queryService!!.startUpdate(queryService!!.nextToken, null, ContentUris.withAppendedId( + Calendars.CONTENT_URI, calendarId), values, null, null, Utils.UNDO_DELAY) + calendarColorListener!!.onColorSelected(color) + } + } + + companion object { + + fun newInstance(calendarId: Long, isTablet: Boolean, newListener: OnCalendarColorSelectedListener): CalendarColorPickerDialogX { + val fragment = CalendarColorPickerDialogX() + fragment.setArguments(R.string.calendar_color_picker_dialog_title, NUM_COLUMNS, if (isTablet) SIZE_LARGE else SIZE_SMALL) + fragment.setCalendarId(calendarId) + fragment.setCalendarColorListener(newListener) + return fragment + } + + internal val CALENDARS_PROJECTION = arrayOf( + Calendars.ACCOUNT_NAME, + Calendars.ACCOUNT_TYPE, + Calendars.CALENDAR_COLOR + ) + internal const val CALENDARS_INDEX_ACCOUNT_NAME = 0 + internal const val CALENDARS_INDEX_ACCOUNT_TYPE = 1 + internal const val CALENDARS_INDEX_CALENDAR_COLOR = 2 + + internal val defaultColors = arrayOf( + -16742839, + -15619228, + -15444807, + -11622631, + -10308462, + -10263092, + -9529671, + -9522247, + -9156171, + -8166452, + -8015812, + -7713480, + -6579301, + -6405704, + -6122346, + -6062974, + -5882570, + -3842946, + -3795456, + -3662334, + -3629779, + -3557812, + -3391744, + -3377396 + ) + + internal val COLORS_PROJECTION = arrayOf( + Colors.COLOR, + Colors.COLOR_KEY + ) + const val COLORS_INDEX_COLOR = 0 + const val COLORS_INDEX_COLOR_KEY = 1 + internal const val COLORS_WHERE = Colors.ACCOUNT_NAME + "=? AND " + + Colors.ACCOUNT_TYPE + "=? AND " + + Colors.COLOR_TYPE + "=" + Colors.TYPE_CALENDAR + + private const val NUM_COLUMNS = 4 + private const val KEY_CALENDAR_ID = "calendar_id" + private const val KEY_COLOR_KEYS = "color_keys" + private const val TOKEN_QUERY_CALENDARS = 1 shl 1 + private const val TOKEN_QUERY_COLORS = 1 shl 2 + } +} diff --git a/src/com/android/calendar/settings/CalendarDataStore.kt b/src/com/android/calendar/settings/CalendarDataStore.kt new file mode 100644 index 000000000..ceb46942d --- /dev/null +++ b/src/com/android/calendar/settings/CalendarDataStore.kt @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2020 Dominik Schürmann + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.android.calendar.settings + +import android.content.ContentUris +import android.content.ContentValues +import android.provider.CalendarContract +import androidx.fragment.app.FragmentActivity +import androidx.preference.PreferenceDataStore + +/** + * Custom data store for preferences that saves/retrieves settings of an individual calendar + * from Android's calendar database. + */ +class CalendarDataStore(activity: FragmentActivity, calendarId: Long) : PreferenceDataStore() { + private var contentResolver = activity.contentResolver + private var calendarUri = ContentUris.withAppendedId(CalendarContract.Calendars.CONTENT_URI, calendarId) + + companion object { + private val PROJECTION = arrayOf( + CalendarContract.Calendars._ID, + CalendarContract.Calendars.SYNC_EVENTS, + CalendarContract.Calendars.VISIBLE, + CalendarContract.Calendars.CALENDAR_COLOR, + CalendarContract.Calendars.CALENDAR_DISPLAY_NAME + ) + } + + private fun mapPreferenceKeyToDatabaseKey(key: String?): String { + return when (key) { + CalendarPreferences.SYNCHRONIZE_KEY -> CalendarContract.Calendars.SYNC_EVENTS + CalendarPreferences.VISIBLE_KEY -> CalendarContract.Calendars.VISIBLE + CalendarPreferences.COLOR_KEY -> CalendarContract.Calendars.CALENDAR_COLOR + CalendarPreferences.DISPLAY_NAME_KEY -> CalendarContract.Calendars.CALENDAR_DISPLAY_NAME + else -> throw UnsupportedOperationException("unsupported preference key") + } + } + + override fun putBoolean(key: String?, value: Boolean) { + val databaseKey = mapPreferenceKeyToDatabaseKey(key) + + val values = ContentValues() + values.put(databaseKey, if (value) 1 else 0) + contentResolver.update(calendarUri, values, null, null) + } + + override fun getBoolean(key: String?, defValue: Boolean): Boolean { + val databaseKey = mapPreferenceKeyToDatabaseKey(key) + + contentResolver.query(calendarUri, PROJECTION, null, null, null)?.use { + if (it.moveToFirst()) { + return it.getInt(it.getColumnIndex(databaseKey)) == 1 + } + } + return defValue + } + + override fun putInt(key: String?, value: Int) { + val databaseKey = mapPreferenceKeyToDatabaseKey(key) + + val values = ContentValues() + values.put(databaseKey, value) + contentResolver.update(calendarUri, values, null, null) + } + + override fun getInt(key: String?, defValue: Int): Int { + val databaseKey = mapPreferenceKeyToDatabaseKey(key) + + contentResolver.query(calendarUri, PROJECTION, null, null, null)?.use { + if (it.moveToFirst()) { + return it.getInt(it.getColumnIndex(databaseKey)) + } + } + return defValue + } + + override fun putString(key: String?, value: String?) { + val databaseKey = mapPreferenceKeyToDatabaseKey(key) + + val values = ContentValues() + values.put(databaseKey, value) + contentResolver.update(calendarUri, values, null, null) + } + + override fun getString(key: String?, defValue: String?): String? { + val databaseKey = mapPreferenceKeyToDatabaseKey(key) + + contentResolver.query(calendarUri, PROJECTION, null, null, null)?.use { + if (it.moveToFirst()) { + return it.getString(it.getColumnIndex(databaseKey)) + } + } + return defValue + } + +} diff --git a/src/com/android/calendar/settings/CalendarPreferences.kt b/src/com/android/calendar/settings/CalendarPreferences.kt new file mode 100644 index 000000000..12add2399 --- /dev/null +++ b/src/com/android/calendar/settings/CalendarPreferences.kt @@ -0,0 +1,203 @@ +/* + * Copyright (C) 2020 Dominik Schürmann + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.android.calendar.settings + +import android.accounts.Account +import android.accounts.AccountManager +import android.accounts.AuthenticatorDescription +import android.graphics.PorterDuff +import android.graphics.drawable.Drawable +import android.os.Bundle +import android.provider.CalendarContract +import android.util.Log +import androidx.appcompat.app.AlertDialog +import androidx.preference.* +import com.android.calendar.Utils +import com.android.calendar.persistence.CalendarRepository +import ws.xsoh.etar.R + +class CalendarPreferences : PreferenceFragmentCompat() { + + private var calendarId: Long = -1 + private lateinit var calendarRepository: CalendarRepository + private lateinit var account: Account + + override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { + calendarId = arguments!!.getLong(ARG_CALENDAR_ID) + calendarRepository = CalendarRepository(activity!!.application) + account = calendarRepository.queryAccount(calendarId)!! + + // use custom data store to save/retrieve calendar preferences in Android's calendar database + val preferenceManager = preferenceManager + preferenceManager.preferenceDataStore = CalendarDataStore(activity!!, calendarId) + + populatePreferences() + } + + private fun populatePreferences() { + val context = preferenceManager.context + val screen = preferenceManager.createPreferenceScreen(context) + + val isLocalAccount = account.type == CalendarContract.ACCOUNT_TYPE_LOCAL + + val synchronizePreference = SwitchPreference(context).apply { + key = SYNCHRONIZE_KEY + title = getString(R.string.preferences_calendar_synchronize) + isEnabled = !isLocalAccount + } + val visiblePreference = SwitchPreference(context).apply { + key = VISIBLE_KEY + title = getString(R.string.preferences_calendar_visible) + } + + val currentColor = preferenceManager.preferenceDataStore!!.getInt(COLOR_KEY, -1) + val colorPreference = Preference(context).apply { + key = COLOR_KEY + title = getString(R.string.preferences_calendar_color) + icon = getColorIcon(currentColor) + } + colorPreference.setOnPreferenceClickListener { + displayCalendarColorPicker() + true + } + + val displayNamePreference = EditTextPreference(context).apply { + key = DISPLAY_NAME_KEY + title = getString(R.string.preferences_calendar_display_name) + dialogTitle = getString(R.string.preferences_calendar_display_name) + isEnabled = isLocalAccount + } + displayNamePreference.setOnPreferenceChangeListener { _, newValue -> + activity?.title = newValue as String + true + } + val deletePreference = Preference(context).apply { + title = getString(R.string.preferences_calendar_delete) + isEnabled = isLocalAccount + } + deletePreference.setOnPreferenceClickListener { + deleteCalendar() + true + } + + screen.addPreference(synchronizePreference) + screen.addPreference(visiblePreference) + screen.addPreference(colorPreference) + screen.addPreference(displayNamePreference) + screen.addPreference(deletePreference) + + val accountCategory = PreferenceCategory(context).apply { + title = getString(R.string.preferences_calendar_account_category) + } + screen.addPreference(accountCategory) + + if (isLocalAccount) { + val localAccountInfoPreference = Preference(context).apply { + title = getString(R.string.preferences_list_add_offline_message) + isSelectable = false + icon = resources.getDrawable(R.drawable.sync_off) + } + accountCategory.addPreference(localAccountInfoPreference) + } else { + addConfigureAccountPreference(accountCategory, account) + } + + preferenceScreen = screen + } + + private fun addConfigureAccountPreference(category: PreferenceCategory, account: Account) { + val description = getAuthenticatorDescription(account) ?: return + + val pm = activity?.packageManager + + val authenticatorLabel = pm?.getResourcesForApplication(description.packageName)?.getString( + description.labelId) + val authenticatorIcon = pm?.getDrawable(description.packageName, description.iconId, null) + val authenticatorIntent = pm?.getLaunchIntentForPackage(description.packageName) + val hasIntent = authenticatorIntent != null + + if (authenticatorLabel != null && authenticatorIcon != null) { + val configureAccountPreference = Preference(context).apply { + title = getString(R.string.preferences_calendar_account, authenticatorLabel) + isEnabled = hasIntent + intent = authenticatorIntent + icon = authenticatorIcon + } + category.addPreference(configureAccountPreference) + } + } + + private fun getColorIcon(color: Int): Drawable { + val icon: Drawable = resources.getDrawable(R.drawable.circle) + icon.mutate().setColorFilter(color, PorterDuff.Mode.SRC_IN) + return icon + } + + private fun displayCalendarColorPicker() { + if (fragmentManager!!.findFragmentByTag(COLOR_PICKER_DIALOG_TAG) != null) { + return + } + + val isTablet = Utils.getConfigBool(context, R.bool.tablet_config) + val calendarDialogPicker = CalendarColorPickerDialogX.newInstance(calendarId, isTablet, + object : CalendarColorPickerDialogX.OnCalendarColorSelectedListener { + override fun onColorSelected(color: Int) { + val colorPref = findPreference(COLOR_KEY)!! + colorPref.icon = getColorIcon(color) + } + }) + calendarDialogPicker.show(fragmentManager!!, COLOR_PICKER_DIALOG_TAG) + } + + private fun getAuthenticatorDescription(account: Account): AuthenticatorDescription? { + val manager = AccountManager.get(context) + val descriptions = manager.authenticatorTypes + for (description in descriptions) { + if (description.type == account.type) { + return description + } + } + return null + } + + private fun deleteCalendar() { + val warningDialog = AlertDialog.Builder(activity!!) + .setMessage(R.string.preferences_calendar_delete_message) + .setPositiveButton(R.string.preferences_calendar_delete_delete) { _, _ -> + calendarRepository.deleteLocalCalendar(account.name, calendarId) + activity?.supportFragmentManager?.popBackStackImmediate() + } + .setNegativeButton(R.string.preferences_calendar_delete_cancel) { dialogInterface, _ -> + dialogInterface.dismiss() + } + .create() + warningDialog.show() + } + + companion object { + const val COLOR_PICKER_DIALOG_TAG = "CalendarColorPickerDialog" + + const val ARG_CALENDAR_ID = "calendarId" + + const val SYNCHRONIZE_KEY = "synchronize" + const val VISIBLE_KEY = "visible" + const val COLOR_KEY = "color" + const val DISPLAY_NAME_KEY = "displayName" + } + +} \ No newline at end of file diff --git a/src/com/android/calendar/settings/ColorPickerDialogX.java b/src/com/android/calendar/settings/ColorPickerDialogX.java new file mode 100644 index 000000000..7bcc5646b --- /dev/null +++ b/src/com/android/calendar/settings/ColorPickerDialogX.java @@ -0,0 +1,198 @@ +package com.android.calendar.settings; + +import android.app.Activity; +import android.app.Dialog; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.ProgressBar; + +import androidx.appcompat.app.AlertDialog; +import androidx.fragment.app.DialogFragment; + +import com.android.colorpicker.ColorPickerPalette; +import com.android.colorpicker.ColorPickerSwatch.OnColorSelectedListener; + +/** + * 1-to-1 Copy of ColorPickerDialog but using androidx classes + */ +public class ColorPickerDialogX extends DialogFragment implements OnColorSelectedListener { + + public static final int SIZE_LARGE = 1; + public static final int SIZE_SMALL = 2; + + protected AlertDialog mAlertDialog; + + protected static final String KEY_TITLE_ID = "title_id"; + protected static final String KEY_COLORS = "colors"; + protected static final String KEY_COLOR_CONTENT_DESCRIPTIONS = "color_content_descriptions"; + protected static final String KEY_SELECTED_COLOR = "selected_color"; + protected static final String KEY_COLUMNS = "columns"; + protected static final String KEY_SIZE = "size"; + + protected int mTitleResId = com.android.colorpicker.R.string.color_picker_default_title; + protected int[] mColors = null; + protected String[] mColorContentDescriptions = null; + protected int mSelectedColor; + protected int mColumns; + protected int mSize; + + private ColorPickerPalette mPalette; + private ProgressBar mProgress; + + protected OnColorSelectedListener mListener; + + public ColorPickerDialogX() { + // Empty constructor required for dialog fragments. + } + + public static ColorPickerDialogX newInstance(int titleResId, int[] colors, int selectedColor, + int columns, int size) { + ColorPickerDialogX ret = new ColorPickerDialogX(); + ret.initialize(titleResId, colors, selectedColor, columns, size); + return ret; + } + + public void initialize(int titleResId, int[] colors, int selectedColor, int columns, int size) { + setArguments(titleResId, columns, size); + setColors(colors, selectedColor); + } + + public void setArguments(int titleResId, int columns, int size) { + Bundle bundle = new Bundle(); + bundle.putInt(KEY_TITLE_ID, titleResId); + bundle.putInt(KEY_COLUMNS, columns); + bundle.putInt(KEY_SIZE, size); + setArguments(bundle); + } + + public void setOnColorSelectedListener(OnColorSelectedListener listener) { + mListener = listener; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + if (getArguments() != null) { + mTitleResId = getArguments().getInt(KEY_TITLE_ID); + mColumns = getArguments().getInt(KEY_COLUMNS); + mSize = getArguments().getInt(KEY_SIZE); + } + + if (savedInstanceState != null) { + mColors = savedInstanceState.getIntArray(KEY_COLORS); + mSelectedColor = (Integer) savedInstanceState.getSerializable(KEY_SELECTED_COLOR); + mColorContentDescriptions = savedInstanceState.getStringArray( + KEY_COLOR_CONTENT_DESCRIPTIONS); + } + } + + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + final Activity activity = getActivity(); + + View view = LayoutInflater.from(getActivity()).inflate(com.android.colorpicker.R.layout.color_picker_dialog, null); + mProgress = (ProgressBar) view.findViewById(android.R.id.progress); + mPalette = (ColorPickerPalette) view.findViewById(com.android.colorpicker.R.id.color_picker); + mPalette.init(mSize, mColumns, this); + + if (mColors != null) { + showPaletteView(); + } + + mAlertDialog = new AlertDialog.Builder(activity) + .setTitle(mTitleResId) + .setView(view) + .create(); + + return mAlertDialog; + } + + @Override + public void onColorSelected(int color) { + if (mListener != null) { + mListener.onColorSelected(color); + } + + if (getTargetFragment() instanceof OnColorSelectedListener) { + final OnColorSelectedListener listener = + (OnColorSelectedListener) getTargetFragment(); + listener.onColorSelected(color); + } + + if (color != mSelectedColor) { + mSelectedColor = color; + // Redraw palette to show checkmark on newly selected color before dismissing. + mPalette.drawPalette(mColors, mSelectedColor); + } + + dismiss(); + } + + public void showPaletteView() { + if (mProgress != null && mPalette != null) { + mProgress.setVisibility(View.GONE); + refreshPalette(); + mPalette.setVisibility(View.VISIBLE); + } + } + + public void showProgressBarView() { + if (mProgress != null && mPalette != null) { + mProgress.setVisibility(View.VISIBLE); + mPalette.setVisibility(View.GONE); + } + } + + public void setColors(int[] colors, int selectedColor) { + if (mColors != colors || mSelectedColor != selectedColor) { + mColors = colors; + mSelectedColor = selectedColor; + refreshPalette(); + } + } + + public void setColors(int[] colors) { + if (mColors != colors) { + mColors = colors; + refreshPalette(); + } + } + + public void setSelectedColor(int color) { + if (mSelectedColor != color) { + mSelectedColor = color; + refreshPalette(); + } + } + + public void setColorContentDescriptions(String[] colorContentDescriptions) { + if (mColorContentDescriptions != colorContentDescriptions) { + mColorContentDescriptions = colorContentDescriptions; + refreshPalette(); + } + } + + private void refreshPalette() { + if (mPalette != null && mColors != null) { + mPalette.drawPalette(mColors, mSelectedColor, mColorContentDescriptions); + } + } + + public int[] getColors() { + return mColors; + } + + public int getSelectedColor() { + return mSelectedColor; + } + + @Override + public void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + outState.putIntArray(KEY_COLORS, mColors); + outState.putSerializable(KEY_SELECTED_COLOR, mSelectedColor); + outState.putStringArray(KEY_COLOR_CONTENT_DESCRIPTIONS, mColorContentDescriptions); + } +} diff --git a/src/com/android/calendar/settings/GeneralPreferences.kt b/src/com/android/calendar/settings/GeneralPreferences.kt new file mode 100644 index 000000000..9daa373e5 --- /dev/null +++ b/src/com/android/calendar/settings/GeneralPreferences.kt @@ -0,0 +1,509 @@ +/* + * Copyright (C) 2020 Dominik Schürmann + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.android.calendar.settings + +import android.annotation.TargetApi +import android.app.backup.BackupManager +import android.content.Context +import android.content.Intent +import android.content.SharedPreferences +import android.content.SharedPreferences.OnSharedPreferenceChangeListener +import android.media.RingtoneManager +import android.net.Uri +import android.os.Build +import android.os.Bundle +import android.os.Vibrator +import android.provider.CalendarContract +import android.provider.CalendarContract.CalendarCache +import android.provider.SearchRecentSuggestions +import android.provider.Settings +import android.text.TextUtils +import android.text.format.Time +import android.util.SparseIntArray +import android.widget.Toast +import androidx.preference.* +import com.android.calendar.* +import com.android.calendar.alerts.AlertReceiver +import com.android.calendar.event.EventViewUtils +import com.android.timezonepicker.TimeZoneInfo +import com.android.timezonepicker.TimeZonePickerUtils +import ws.xsoh.etar.R + +class GeneralPreferences : PreferenceFragmentCompat(), + OnSharedPreferenceChangeListener, Preference.OnPreferenceChangeListener, + TimeZonePickerDialogX.OnTimeZoneSetListener { + + // >= 26 + private var mNotification: Preference? = null + + // < 26 + private lateinit var mAlert: CheckBoxPreference + private lateinit var mRingtone: Preference + private lateinit var mVibrate: CheckBoxPreference + + private lateinit var mPopup: CheckBoxPreference + private lateinit var mUseHomeTZ: CheckBoxPreference + private lateinit var mHideDeclined: CheckBoxPreference + private var mHomeTZ: Preference? = null + private var mTzPickerUtils: TimeZonePickerUtils? = null + private lateinit var mTheme: ListPreference + private var mColor: Preference? = null + private lateinit var mWeekStart: ListPreference + private lateinit var mDayWeek: ListPreference + private lateinit var mDefaultReminder: ListPreference + private lateinit var mDefaultEventDuration: ListPreference + private lateinit var mSnoozeDelay: ListPreference + private lateinit var mDefaultStart: ListPreference + + private var mTimeZoneId: String? = null + + // Used to retrieve the color id from the color picker + private val colorMap = SparseIntArray() + + override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { + // use old shared preferences name to be backward compatible + preferenceManager.sharedPreferencesName = SHARED_PREFS_NAME + + if (Utils.isOreoOrLater()) { + setPreferencesFromResource(R.xml.general_preferences_oreo_and_up, rootKey) + } else { + setPreferencesFromResource(R.xml.general_preferences_nougat_and_less, rootKey) + } + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + initializeColorMap() + + val prefs = CalendarUtils.getSharedPreferences(activity!!, + Utils.SHARED_PREFS_NAME) + + if (Utils.isOreoOrLater()) { + mNotification = preferenceScreen.findPreference(KEY_NOTIFICATION) + } else { + mAlert = preferenceScreen.findPreference(KEY_ALERTS)!! + mVibrate = preferenceScreen.findPreference(KEY_ALERTS_VIBRATE)!! + val vibrator = activity!!.getSystemService(Context.VIBRATOR_SERVICE) as Vibrator + if (!vibrator.hasVibrator()) { + val mAlertGroup = preferenceScreen + .findPreference(KEY_ALERTS_CATEGORY) as PreferenceCategory? + mAlertGroup!!.removePreference(mVibrate) + } + mRingtone = preferenceScreen.findPreference(KEY_ALERTS_RINGTONE)!! + val ringToneUri = Utils.getRingTonePreference(activity) + + // Set the ringToneUri to the backup-able shared pref only so that + // the Ringtone dialog will open up with the correct value. + val editor = prefs.edit() + editor.putString(KEY_ALERTS_RINGTONE, ringToneUri).apply() + + val ringtoneDisplayString = getRingtoneTitleFromUri(activity!!, ringToneUri) + mRingtone.summary = ringtoneDisplayString ?: "" + } + + mPopup = preferenceScreen.findPreference(KEY_ALERTS_POPUP)!! + mUseHomeTZ = preferenceScreen.findPreference(KEY_HOME_TZ_ENABLED)!! + mTheme = preferenceScreen.findPreference(KEY_THEME_PREF)!! + mColor = preferenceScreen.findPreference(KEY_COLOR_PREF)!! + mDefaultStart = preferenceScreen.findPreference(KEY_DEFAULT_START)!! + mHideDeclined = preferenceScreen.findPreference(KEY_HIDE_DECLINED)!! + mWeekStart = preferenceScreen.findPreference(KEY_WEEK_START_DAY)!! + mDayWeek = preferenceScreen.findPreference(KEY_DAYS_PER_WEEK)!! + mDefaultReminder = preferenceScreen.findPreference(KEY_DEFAULT_REMINDER)!! + mDefaultEventDuration = preferenceScreen.findPreference(KEY_DEFAULT_EVENT_DURATION)!! + mDefaultEventDuration.summary = mDefaultEventDuration.entry + mHomeTZ = preferenceScreen.findPreference(KEY_HOME_TZ) + mSnoozeDelay = preferenceScreen.findPreference(KEY_DEFAULT_SNOOZE_DELAY)!! + buildSnoozeDelayEntries() + mTheme.summary = mTheme.entry + mWeekStart.summary = mWeekStart.entry + mDayWeek.summary = mDayWeek.entry + mDefaultReminder.summary = mDefaultReminder.entry + mSnoozeDelay.summary = mSnoozeDelay.entry + mDefaultStart.summary = mDefaultStart.entry + + // This triggers an asynchronous call to the provider to refresh the data in shared pref + mTimeZoneId = Utils.getTimeZone(activity, null) + + // Utils.getTimeZone will return the currentTimeZone instead of the one + // in the shared_pref if home time zone is disabled. So if home tz is + // off, we will explicitly read it. + if (!prefs.getBoolean(KEY_HOME_TZ_ENABLED, false)) { + mTimeZoneId = prefs.getString(KEY_HOME_TZ, Time.getCurrentTimezone()) + } + + if (mTzPickerUtils == null) { + mTzPickerUtils = TimeZonePickerUtils(activity) + } + val timezoneName = mTzPickerUtils!!.getGmtDisplayName(activity, mTimeZoneId, + System.currentTimeMillis(), false) + mHomeTZ!!.summary = timezoneName ?: mTimeZoneId + + val tzpd = activity!!.supportFragmentManager + .findFragmentByTag(FRAG_TAG_TIME_ZONE_PICKER) as TimeZonePickerDialogX? + tzpd?.setOnTimeZoneSetListener(this) + } + + private fun showColorPickerDialog() { + val colorPickerDialog = ColorPickerDialogX() + val selectedColorName = Utils.getSharedPreference(activity, KEY_COLOR_PREF, "teal") + val selectedColor = resources.getColor(DynamicTheme.getColorId(selectedColorName)) + colorPickerDialog.initialize(R.string.preferences_color_pick, + intArrayOf(resources.getColor(R.color.colorPrimary), + resources.getColor(R.color.colorBluePrimary), + resources.getColor(R.color.colorPurplePrimary), + resources.getColor(R.color.colorRedPrimary), + resources.getColor(R.color.colorOrangePrimary), + resources.getColor(R.color.colorGreenPrimary)), + selectedColor, 3, 2) + colorPickerDialog.setOnColorSelectedListener { colour -> + Utils.setSharedPreference(activity, KEY_COLOR_PREF, DynamicTheme.getColorName(colorMap.get(colour))) + } + colorPickerDialog.show(fragmentManager!!, "colorpicker") + } + + private fun initializeColorMap() { + colorMap.put(resources.getColor(R.color.colorPrimary), R.color.colorPrimary) + colorMap.put(resources.getColor(R.color.colorBluePrimary), R.color.colorBluePrimary) + colorMap.put(resources.getColor(R.color.colorOrangePrimary), R.color.colorOrangePrimary) + colorMap.put(resources.getColor(R.color.colorGreenPrimary), R.color.colorGreenPrimary) + colorMap.put(resources.getColor(R.color.colorRedPrimary), R.color.colorRedPrimary) + colorMap.put(resources.getColor(R.color.colorPurplePrimary), R.color.colorPurplePrimary) + } + + private fun showTimezoneDialog() { + val arguments = Bundle().apply { + putLong(TimeZonePickerDialogX.BUNDLE_START_TIME_MILLIS, System.currentTimeMillis()) + putString(TimeZonePickerDialogX.BUNDLE_TIME_ZONE, Utils.getTimeZone(activity, null)) + } + + val fm = activity!!.supportFragmentManager + var tzpd: TimeZonePickerDialogX? = fm.findFragmentByTag(FRAG_TAG_TIME_ZONE_PICKER) as TimeZonePickerDialogX? + tzpd?.dismiss() + + tzpd = TimeZonePickerDialogX() + tzpd.arguments = arguments + tzpd.setOnTimeZoneSetListener(this) + tzpd.show(fm, FRAG_TAG_TIME_ZONE_PICKER) + } + + override fun onStart() { + super.onStart() + preferenceScreen.sharedPreferences.registerOnSharedPreferenceChangeListener(this) + setPreferenceListeners(this) + } + + /** + * Sets up all the preference change listeners to use the specified listener. + */ + private fun setPreferenceListeners(listener: Preference.OnPreferenceChangeListener) { + mUseHomeTZ.onPreferenceChangeListener = listener + mHomeTZ!!.onPreferenceChangeListener = listener + mTheme.onPreferenceChangeListener = listener + mColor!!.onPreferenceChangeListener = listener + mDefaultStart.onPreferenceChangeListener = listener + mWeekStart.onPreferenceChangeListener = listener + mDayWeek.onPreferenceChangeListener = listener + mDefaultReminder.onPreferenceChangeListener = listener + mSnoozeDelay.onPreferenceChangeListener = listener + mHideDeclined.onPreferenceChangeListener = listener + mDefaultEventDuration.onPreferenceChangeListener = listener + if (Utils.isOreoOrLater()) { + mNotification!!.onPreferenceChangeListener = listener + } else { + mVibrate.onPreferenceChangeListener = listener + } + } + + override fun onStop() { + preferenceScreen.sharedPreferences.unregisterOnSharedPreferenceChangeListener(this) + super.onStop() + } + + override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) { + val a = activity ?: return + + BackupManager.dataChanged(a.packageName) + + when (key) { + KEY_ALERTS -> { + val intent = Intent() + intent.setClass(a, AlertReceiver::class.java) + if (mAlert.isChecked) { + intent.action = AlertReceiver.ACTION_DISMISS_OLD_REMINDERS + } else { + intent.action = AlertReceiver.EVENT_REMINDER_APP_ACTION + } + a.sendBroadcast(intent) + } + KEY_THEME_PREF -> a.recreate() + KEY_COLOR_PREF -> a.recreate() + } + } + + override fun onPreferenceChange(preference: Preference, newValue: Any): Boolean { + when (preference) { + mUseHomeTZ -> { + val useHomeTz = newValue as Boolean + val tz: String? = if (useHomeTz) { + mTimeZoneId + } else { + CalendarCache.TIMEZONE_TYPE_AUTO + } + Utils.setTimeZone(activity, tz) + return true + } + mTheme -> { + mTheme.value = newValue as String + mTheme.summary = mTheme.entry + } + mHideDeclined -> { + mHideDeclined.isChecked = newValue as Boolean + val intent = Intent(Utils.getWidgetScheduledUpdateAction(activity)) + intent.setDataAndType(CalendarContract.CONTENT_URI, Utils.APPWIDGET_DATA_TYPE) + activity!!.sendBroadcast(intent) + return true + } + mWeekStart -> { + mWeekStart.value = newValue as String + mWeekStart.summary = mWeekStart.entry + } + mDayWeek -> { + mDayWeek.value = newValue as String + mDayWeek.summary = mDayWeek.entry + } + mDefaultEventDuration -> { + mDefaultEventDuration.value = newValue as String + mDefaultEventDuration.summary = mDefaultEventDuration.entry + } + mDefaultReminder -> { + mDefaultReminder.value = newValue as String + mDefaultReminder.summary = mDefaultReminder.entry + } + mSnoozeDelay -> { + mSnoozeDelay.value = newValue as String + mSnoozeDelay.summary = mSnoozeDelay.entry + } + mVibrate -> { + mVibrate.isChecked = newValue as Boolean + return true + } + mDefaultStart -> { + val i = mDefaultStart.findIndexOfValue(newValue as String) + mDefaultStart.summary = mDefaultStart.entries[i] + return true + } + else -> { + return true + } + } + return false + } + + private fun getRingtoneTitleFromUri(context: Context, uri: String): String? { + if (TextUtils.isEmpty(uri)) { + return null + } + + val ring = RingtoneManager.getRingtone(activity, Uri.parse(uri)) + return ring?.getTitle(context) + } + + private fun buildSnoozeDelayEntries() { + val values = mSnoozeDelay.entryValues + val count = values.size + val entries = arrayOfNulls(count) + + for (i in 0 until count) { + val value = Integer.parseInt(values[i].toString()) + entries[i] = EventViewUtils.constructReminderLabel(activity!!, value, false) + } + + mSnoozeDelay.entries = entries + } + + override fun onPreferenceTreeClick(preference: Preference?): Boolean { + val key = preference!!.key; + + when (key) { + KEY_HOME_TZ -> { + showTimezoneDialog() + return true + } + KEY_COLOR_PREF -> { + showColorPickerDialog() + return true + } + KEY_ALERTS_RINGTONE -> { + showRingtoneManager() + return true + } + KEY_CLEAR_SEARCH_HISTORY -> { + clearSearchHistory() + return true + } + KEY_NOTIFICATION -> { + showNotificationChannel() + return true + } + else -> return super.onPreferenceTreeClick(preference) + } + } + + private fun clearSearchHistory() { + val suggestions = SearchRecentSuggestions(activity, + Utils.getSearchAuthority(activity), + CalendarRecentSuggestionsProvider.MODE) + suggestions.clearHistory() + Toast.makeText(activity, R.string.search_history_cleared, Toast.LENGTH_SHORT).show() + } + + @TargetApi(Build.VERSION_CODES.O) + private fun showNotificationChannel() { + val intent = Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS).apply { + putExtra(Settings.EXTRA_CHANNEL_ID, "alert_channel_01") + putExtra(Settings.EXTRA_APP_PACKAGE, activity!!.packageName) + } + startActivity(intent) + } + + // AndroidX does not include RingtonePreference + // This code is based on https://issuetracker.google.com/issues/37057453#comment3 + private fun showRingtoneManager() { + val intent = Intent(RingtoneManager.ACTION_RINGTONE_PICKER).apply { + putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, RingtoneManager.TYPE_NOTIFICATION) + putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_DEFAULT, true) + putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_SILENT, true) + putExtra(RingtoneManager.EXTRA_RINGTONE_DEFAULT_URI, Settings.System.DEFAULT_NOTIFICATION_URI) + } + + val existingValue = Utils.getRingTonePreference(activity) + if (existingValue != null) { + if (existingValue.isEmpty()) { + // Select "Silent" + intent.putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, null as Uri) + } else { + intent.putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, Uri.parse(existingValue)) + } + } else { + // No ringtone has been selected, set to the default + intent.putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, Settings.System.DEFAULT_NOTIFICATION_URI) + } + + startActivityForResult(intent, REQUEST_CODE_ALERT_RINGTONE) + } + + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + if (requestCode == REQUEST_CODE_ALERT_RINGTONE && data != null) { + val ringtone = data.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI) + if (ringtone != null) { + Utils.setRingTonePreference(activity, ringtone.toString()) + } else { + // "Silent" was selected + Utils.setRingTonePreference(activity, "") + } + + val ringtoneDisplayString = getRingtoneTitleFromUri(activity!!, ringtone.toString()) + mRingtone.summary = ringtoneDisplayString ?: "" + } else { + super.onActivityResult(requestCode, resultCode, data) + } + } + + override fun onTimeZoneSet(tzi: TimeZoneInfo) { + if (mTzPickerUtils == null) { + mTzPickerUtils = TimeZonePickerUtils(activity) + } + + val timezoneName = mTzPickerUtils!!.getGmtDisplayName( + activity, tzi.mTzId, System.currentTimeMillis(), false) + mHomeTZ!!.summary = timezoneName + Utils.setTimeZone(activity, tzi.mTzId) + } + + companion object { + // Preference keys + const val KEY_THEME_PREF = "pref_theme" + const val KEY_COLOR_PREF = "pref_color" + const val KEY_DEFAULT_START = "preferences_default_start" + const val KEY_HIDE_DECLINED = "preferences_hide_declined" + const val KEY_WEEK_START_DAY = "preferences_week_start_day" + const val KEY_SHOW_WEEK_NUM = "preferences_show_week_num" + const val KEY_DAYS_PER_WEEK = "preferences_days_per_week" + const val KEY_MDAYS_PER_WEEK = "preferences_mdays_per_week" + const val KEY_SKIP_SETUP = "preferences_skip_setup" + const val KEY_CLEAR_SEARCH_HISTORY = "preferences_clear_search_history" + const val KEY_ALERTS_CATEGORY = "preferences_alerts_category" + const val KEY_ALERTS = "preferences_alerts" + const val KEY_NOTIFICATION = "preferences_notification" + const val KEY_ALERTS_VIBRATE = "preferences_alerts_vibrate" + const val KEY_ALERTS_RINGTONE = "preferences_alerts_ringtone" + const val KEY_ALERTS_POPUP = "preferences_alerts_popup" + const val KEY_SHOW_CONTROLS = "preferences_show_controls" + const val KEY_DEFAULT_REMINDER = "preferences_default_reminder" + const val NO_REMINDER = -1 + const val NO_REMINDER_STRING = "-1" + const val REMINDER_DEFAULT_TIME = 10 // in minutes + const val KEY_USE_CUSTOM_SNOOZE_DELAY = "preferences_custom_snooze_delay" + const val KEY_DEFAULT_SNOOZE_DELAY = "preferences_default_snooze_delay" + const val SNOOZE_DELAY_DEFAULT_TIME = 5 // in minutes + const val KEY_DEFAULT_CELL_HEIGHT = "preferences_default_cell_height" + const val KEY_VERSION = "preferences_version" + /** Key to SharePreference for default view (CalendarController.ViewType) */ + const val KEY_START_VIEW = "preferred_startView" + /** + * Key to SharePreference for default detail view (CalendarController.ViewType) + * Typically used by widget + */ + const val KEY_DETAILED_VIEW = "preferred_detailedView" + const val KEY_DEFAULT_CALENDAR = "preference_defaultCalendar" + + /** Key to preference for default new event duration (if provider doesn't indicate one) */ + const val KEY_DEFAULT_EVENT_DURATION = "preferences_default_event_duration" + const val EVENT_DURATION_DEFAULT = "60" + + // These must be in sync with the array preferences_week_start_day_values + const val WEEK_START_DEFAULT = "-1" + const val WEEK_START_SATURDAY = "7" + const val WEEK_START_SUNDAY = "1" + const val WEEK_START_MONDAY = "2" + // Default preference values + const val DEFAULT_DEFAULT_START = "-2" + const val DEFAULT_START_VIEW = CalendarController.ViewType.WEEK + const val DEFAULT_DETAILED_VIEW = CalendarController.ViewType.DAY + const val DEFAULT_SHOW_WEEK_NUM = false + // This should match the XML file. + const val DEFAULT_RINGTONE = "content://settings/system/notification_sound" + // The name of the shared preferences file. This name must be maintained for historical + // reasons, as it's what PreferenceManager assigned the first time the file was created. + const val SHARED_PREFS_NAME = "com.android.calendar_preferences" + const val SHARED_PREFS_NAME_NO_BACKUP = "com.android.calendar_preferences_no_backup" + private const val KEY_HOME_TZ_ENABLED = "preferences_home_tz_enabled" + private const val KEY_HOME_TZ = "preferences_home_tz" + private const val FRAG_TAG_TIME_ZONE_PICKER = "TimeZonePicker" + + + internal const val REQUEST_CODE_ALERT_RINGTONE = 42 + + /** Return a properly configured SharedPreferences instance */ + fun getSharedPreferences(context: Context): SharedPreferences { + return context.getSharedPreferences(SHARED_PREFS_NAME, Context.MODE_PRIVATE) + } + } +} diff --git a/src/com/android/calendar/settings/MainListPreferences.kt b/src/com/android/calendar/settings/MainListPreferences.kt new file mode 100644 index 000000000..adcfc2c0b --- /dev/null +++ b/src/com/android/calendar/settings/MainListPreferences.kt @@ -0,0 +1,209 @@ +/* + * Copyright (C) 2020 Dominik Schürmann + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.android.calendar.settings + +import android.content.Intent +import android.graphics.PorterDuff +import android.graphics.drawable.Drawable +import android.net.Uri +import android.os.Bundle +import android.widget.Toast +import androidx.appcompat.app.AppCompatActivity +import androidx.lifecycle.Observer +import androidx.lifecycle.ViewModelProvider +import androidx.preference.Preference +import androidx.preference.PreferenceCategory +import androidx.preference.PreferenceFragmentCompat +import androidx.preference.PreferenceScreen +import com.android.calendar.persistence.Calendar +import ws.xsoh.etar.R + + +class MainListPreferences : PreferenceFragmentCompat() { + + private lateinit var mainListViewModel: MainListViewModel + + private var currentCalendars = mutableSetOf() + + override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { + val context = preferenceManager.context + val screen = preferenceManager.createPreferenceScreen(context) + + addGeneralPreferences(screen) + + preferenceScreen = screen + } + + override fun onActivityCreated(savedInstanceState: Bundle?) { + super.onActivityCreated(savedInstanceState) + + val factory = MainListViewModelFactory(activity!!.application) + mainListViewModel = ViewModelProvider(this, factory).get(MainListViewModel::class.java) + + // Add an observer on the LiveData returned by getCalendarsOrderedByAccount. + // The onChanged() method fires when the observed data changes and the activity is + // in the foreground. + mainListViewModel.getCalendarsOrderedByAccount().observe(viewLifecycleOwner, Observer> { calendars -> + updateAccountsPreferences(preferenceScreen, calendars) + }) + } + + private fun updateAccountsPreferences(screen: PreferenceScreen, allCalendars: List) { + val newCalendars = mutableSetOf() + + for (calendar in allCalendars) { + newCalendars.add(calendar.id) + + // add category per account if not already present + val accountCategoryUniqueKey = "account_category_${calendar.accountName}_${calendar.accountType}" + var accountCategory = screen.findPreference(accountCategoryUniqueKey) + if (accountCategory == null) { + accountCategory = PreferenceCategory(context).apply { + key = accountCategoryUniqueKey + title = calendar.accountName + isOrderingAsAdded = false + } + screen.addPreference(accountCategory) + } + + // add preference per calendar if not already present + val calendarUniqueKey = "calendar_preference_${calendar.id}" + var calendarPreference = screen.findPreference(calendarUniqueKey) + if (calendarPreference == null) { + calendarPreference = Preference(context) + accountCategory.addPreference(calendarPreference) + } + calendarPreference.apply { + key = calendarUniqueKey + title = calendar.displayName + fragment = CalendarPreferences::class.java.name + order = if (calendar.isPrimary) 2 else 3 // primary calendar is first, others are alphabetically ordered below + icon = getCalendarIcon(calendar.color, calendar.visible, calendar.syncEvents) + summary = getCalendarSummary(calendar.visible, calendar.syncEvents) + } + // pass-through calendar id for CalendarPreferences + calendarPreference.extras.putLong(CalendarPreferences.ARG_CALENDAR_ID, calendar.id) + } + + // remove preferences for calendars no longer existing + val toDelete = currentCalendars.subtract(newCalendars) + toDelete.forEach { + val calendarUniqueKey = "calendar_preference_${it}" + screen.removePreferenceRecursively(calendarUniqueKey) + } + currentCalendars = newCalendars + } + + private fun getCalendarSummary(visible: Boolean, syncEvents: Boolean): String { + return if (!syncEvents) { + getString(R.string.preferences_list_calendar_summary_sync_off) + } else if (visible) { + "" + } else { + getString(R.string.preferences_list_calendar_summary_invisible) + } + } + + private fun getCalendarIcon(color: Int, visible: Boolean, syncEvents: Boolean): Drawable { + val icon = if (!syncEvents) { + resources.getDrawable(R.drawable.sync_off) + } else if (visible) { + resources.getDrawable(R.drawable.circle) + } else { + resources.getDrawable(R.drawable.circle_outline) + } + + icon.mutate().setColorFilter(color, PorterDuff.Mode.SRC_IN) + return icon + } + + private fun addGeneralPreferences(screen: PreferenceScreen) { + val generalPreference = Preference(context).apply { + title = getString(R.string.preferences_list_general) + fragment = GeneralPreferences::class.java.name + } + val addCaldavPreference = Preference(context).apply { + title = getString(R.string.preferences_list_add_remote) + } + addCaldavPreference.setOnPreferenceClickListener { + launchDavX5Login() + true + } + val addOfflinePreference = Preference(context).apply { + title = getString(R.string.preferences_list_add_offline) + } + addOfflinePreference.setOnPreferenceClickListener { + addOfflineCalendar() + true + } + val aboutPreference = Preference(context).apply { + title = getString(R.string.preferences_list_about) + fragment = AboutPreferences::class.java.name + } + screen.addPreference(generalPreference) + screen.addPreference(addCaldavPreference) + screen.addPreference(addOfflinePreference) + screen.addPreference(aboutPreference) + } + + private fun addOfflineCalendar() { + val dialog = AddOfflineCalendarDialogFragment() + dialog.show(fragmentManager!!, "addOfflineCalendar") + } + + /** + * Based on https://www.davx5.com/manual/technical_information.html#api-integration + */ + private fun launchDavX5Login() { + val davX5Intent = Intent() + davX5Intent.setClassName("at.bitfire.davdroid", "at.bitfire.davdroid.ui.setup.LoginActivity") + + if (activity!!.packageManager.resolveActivity(davX5Intent, 0) != null) { + startActivityForResult(davX5Intent, ACTION_REQUEST_CODE_DAVX5_SETUP) + } else { + // DAVx5 is not installed + val installIntent = Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=at.bitfire.davdroid")) + + // launch market + if (installIntent.resolveActivity(activity!!.packageManager) != null) { + startActivity(installIntent) + } else { + // no f-droid market app or Play store installed -> launch browser for f-droid url + val downloadIntent = Intent(Intent.ACTION_VIEW, + Uri.parse("https://f-droid.org/repository/browse/?fdid=at.bitfire.davdroid")) + if (downloadIntent.resolveActivity(activity!!.packageManager) != null) { + startActivity(downloadIntent) + } else { + Toast.makeText(activity, "No browser available!", Toast.LENGTH_LONG).show() + } + } + } + } + + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + super.onActivityResult(requestCode, resultCode, data) + + if (requestCode == ACTION_REQUEST_CODE_DAVX5_SETUP && resultCode == AppCompatActivity.RESULT_OK) { + Toast.makeText(activity, "CalDAV account added!", Toast.LENGTH_LONG).show() + } + } + + companion object { + private const val ACTION_REQUEST_CODE_DAVX5_SETUP = 10 + } +} \ No newline at end of file diff --git a/src/com/android/calendar/settings/MainListViewModel.kt b/src/com/android/calendar/settings/MainListViewModel.kt new file mode 100644 index 000000000..b44161c09 --- /dev/null +++ b/src/com/android/calendar/settings/MainListViewModel.kt @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2020 Dominik Schürmann + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.android.calendar.settings + +import android.app.Application +import androidx.lifecycle.AndroidViewModel +import androidx.lifecycle.LiveData +import com.android.calendar.persistence.Calendar +import com.android.calendar.persistence.CalendarRepository + + +class MainListViewModel(application: Application) : AndroidViewModel(application) { + + private var repository: CalendarRepository = CalendarRepository(application) + + // Using LiveData and caching what fetchCalendarsByAccountName returns has several benefits: + // - We can put an observer on the data (instead of polling for changes) and only update the + // the UI when the data actually changes. + // - Repository is completely separated from the UI through the ViewModel. + private lateinit var allCalendars: LiveData> + + init { + loadCalendars() // ViewModel is created only once during Activity/Fragment lifetime + } + + private fun loadCalendars() { + allCalendars = repository.getCalendarsOrderedByAccount() + } + + fun getCalendarsOrderedByAccount(): LiveData> { + return allCalendars + } + +} diff --git a/src/com/android/calendar/settings/MainListViewModelFactory.kt b/src/com/android/calendar/settings/MainListViewModelFactory.kt new file mode 100644 index 000000000..60aa2e0c4 --- /dev/null +++ b/src/com/android/calendar/settings/MainListViewModelFactory.kt @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2020 Dominik Schürmann + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.android.calendar.settings + +import android.app.Application +import androidx.annotation.NonNull +import androidx.lifecycle.ViewModel +import androidx.lifecycle.ViewModelProvider + + +class MainListViewModelFactory(private val application: Application) : ViewModelProvider.Factory { + + @NonNull + override fun create(@NonNull modelClass: Class): T { + if (modelClass.isAssignableFrom(MainListViewModel::class.java)) { + return MainListViewModel(application) as T + } + throw IllegalArgumentException("Unknown ViewModel class") + } +} diff --git a/src/com/android/calendar/settings/QuickResponsePreferences.kt b/src/com/android/calendar/settings/QuickResponsePreferences.kt new file mode 100644 index 000000000..50b561d00 --- /dev/null +++ b/src/com/android/calendar/settings/QuickResponsePreferences.kt @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2020 Dominik Schürmann + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.android.calendar.settings + +import android.os.Bundle +import androidx.preference.EditTextPreference +import androidx.preference.Preference +import androidx.preference.PreferenceFragmentCompat +import androidx.preference.PreferenceScreen +import com.android.calendar.Utils +import ws.xsoh.etar.R +import java.util.* + +/** + * Fragment to facilitate editing of quick responses when emailing guests + */ +class QuickResponsePreferences : PreferenceFragmentCompat(), Preference.OnPreferenceChangeListener { + private lateinit var editTextPrefs: Array + private lateinit var responses: Array + + override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { + val context = preferenceManager.context + val screen = preferenceManager.createPreferenceScreen(context) + + addResponsePreferences(screen) + + preferenceScreen = screen + } + + private fun addResponsePreferences(screen: PreferenceScreen) { + responses = Utils.getQuickResponses(activity) + + editTextPrefs = arrayOfNulls(responses.size) + Arrays.sort(responses) + var i = 0 + for (response in responses) { + val editTextPreference = EditTextPreference(activity).apply { + setDialogTitle(R.string.quick_response_settings_edit_title) + title = response + text = response + key = i.toString() + } + editTextPreference.onPreferenceChangeListener = this + + editTextPrefs[i++] = editTextPreference + screen.addPreference(editTextPreference) + } + } + + override fun onPreferenceChange(preference: Preference, newValue: Any): Boolean { + for (i in editTextPrefs.indices) { + if (editTextPrefs[i]!!.compareTo(preference) == 0) { + if (responses[i] != newValue) { + responses[i] = newValue as String + editTextPrefs[i]!!.title = responses[i] + editTextPrefs[i]!!.text = responses[i] + Utils.setSharedPreference(activity, Utils.KEY_QUICK_RESPONSES, responses) + } + return true + } + } + return false + } + +} \ No newline at end of file diff --git a/src/com/android/calendar/settings/SettingsActivity.kt b/src/com/android/calendar/settings/SettingsActivity.kt new file mode 100644 index 000000000..3c0d21b1d --- /dev/null +++ b/src/com/android/calendar/settings/SettingsActivity.kt @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2020 Dominik Schürmann + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.android.calendar.settings + +import android.os.Bundle +import androidx.appcompat.app.AppCompatActivity +import androidx.appcompat.widget.Toolbar +import androidx.preference.Preference +import androidx.preference.PreferenceFragmentCompat +import com.android.calendar.DynamicTheme +import ws.xsoh.etar.R + + +private const val TITLE_TAG = "settingsActivityTitle" + +class SettingsActivity : AppCompatActivity(), + PreferenceFragmentCompat.OnPreferenceStartFragmentCallback { + + private val dynamicTheme = DynamicTheme() + + override fun onCreate(savedInstanceState: Bundle?) { + dynamicTheme.onCreate(this) + super.onCreate(savedInstanceState) + + setContentView(R.layout.simple_frame_layout_material) + val toolbar = findViewById(R.id.toolbar) + setSupportActionBar(toolbar) + + if (savedInstanceState == null) { + supportFragmentManager + .beginTransaction() + .replace(R.id.body_frame, MainListPreferences()) + .commit() + } else { + title = savedInstanceState.getCharSequence(TITLE_TAG) + } + supportFragmentManager.addOnBackStackChangedListener { + if (supportFragmentManager.backStackEntryCount == 0) { + setTitle(R.string.preferences_title) + } + } + supportActionBar?.setDisplayHomeAsUpEnabled(true) + } + + override fun onSaveInstanceState(outState: Bundle) { + super.onSaveInstanceState(outState) + // Save current activity title so we can set it again after a configuration change + outState.putCharSequence(TITLE_TAG, title) + } + + override fun onSupportNavigateUp(): Boolean { + if (supportFragmentManager.popBackStackImmediate()) { + return true + } + return super.onSupportNavigateUp() + } + + override fun onPreferenceStartFragment( + caller: PreferenceFragmentCompat, + pref: Preference + ): Boolean { + // Instantiate the new Fragment + val args = pref.extras + val fragment = supportFragmentManager.fragmentFactory.instantiate( + classLoader, + pref.fragment + ).apply { + arguments = args + setTargetFragment(caller, 0) + } + // Replace the existing Fragment with the new Fragment + supportFragmentManager.beginTransaction() + .replace(R.id.body_frame, fragment) + .addToBackStack(null) + .commit() + title = pref.title + return true + } + + override fun onResume() { + super.onResume() + dynamicTheme.onResume(this) + } +} diff --git a/src/com/android/calendar/settings/TimeZonePickerDialogX.java b/src/com/android/calendar/settings/TimeZonePickerDialogX.java new file mode 100644 index 000000000..42942e292 --- /dev/null +++ b/src/com/android/calendar/settings/TimeZonePickerDialogX.java @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.calendar.settings; + +import android.app.Dialog; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.Window; +import android.view.WindowManager; + +import androidx.fragment.app.DialogFragment; + +import com.android.timezonepicker.TimeZoneInfo; +import com.android.timezonepicker.TimeZonePickerView; + +/** + * 1-to-1 Copy of TimeZonePickerDialog but using androidx classes + */ +public class TimeZonePickerDialogX extends DialogFragment implements + TimeZonePickerView.OnTimeZoneSetListener { + public static final String TAG = TimeZonePickerDialogX.class.getSimpleName(); + + public static final String BUNDLE_START_TIME_MILLIS = "bundle_event_start_time"; + public static final String BUNDLE_TIME_ZONE = "bundle_event_time_zone"; + + private static final String KEY_HAS_RESULTS = "has_results"; + private static final String KEY_LAST_FILTER_STRING = "last_filter_string"; + private static final String KEY_LAST_FILTER_TYPE = "last_filter_type"; + private static final String KEY_LAST_FILTER_TIME = "last_filter_time"; + private static final String KEY_HIDE_FILTER_SEARCH = "hide_filter_search"; + + private OnTimeZoneSetListener mTimeZoneSetListener; + private TimeZonePickerView mView; + private boolean mHasCachedResults = false; + + public interface OnTimeZoneSetListener { + void onTimeZoneSet(TimeZoneInfo tzi); + } + + public void setOnTimeZoneSetListener(OnTimeZoneSetListener l) { + mTimeZoneSetListener = l; + } + + public TimeZonePickerDialogX() { + super(); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + long timeMillis = 0; + String timeZone = null; + Bundle b = getArguments(); + if (b != null) { + timeMillis = b.getLong(BUNDLE_START_TIME_MILLIS); + timeZone = b.getString(BUNDLE_TIME_ZONE); + } + boolean hideFilterSearch = false; + + if (savedInstanceState != null) { + hideFilterSearch = savedInstanceState.getBoolean(KEY_HIDE_FILTER_SEARCH); + } + mView = new TimeZonePickerView(getActivity(), null, timeZone, timeMillis, this, + hideFilterSearch); + if (savedInstanceState != null && savedInstanceState.getBoolean(KEY_HAS_RESULTS, false)) { + mView.showFilterResults(savedInstanceState.getInt(KEY_LAST_FILTER_TYPE), + savedInstanceState.getString(KEY_LAST_FILTER_STRING), + savedInstanceState.getInt(KEY_LAST_FILTER_TIME)); + } + return mView; + } + + @Override + public void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + outState.putBoolean(KEY_HAS_RESULTS, mView != null && mView.hasResults()); + if (mView != null) { + outState.putInt(KEY_LAST_FILTER_TYPE, mView.getLastFilterType()); + outState.putString(KEY_LAST_FILTER_STRING, mView.getLastFilterString()); + outState.putInt(KEY_LAST_FILTER_TIME, mView.getLastFilterTime()); + outState.putBoolean(KEY_HIDE_FILTER_SEARCH, mView.getHideFilterSearchOnStart()); + } + } + + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + Dialog dialog = super.onCreateDialog(savedInstanceState); + dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); + dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); + return dialog; + } + + @Override + public void onTimeZoneSet(TimeZoneInfo tzi) { + if (mTimeZoneSetListener != null) { + mTimeZoneSetListener.onTimeZoneSet(tzi); + } + dismiss(); + } +} diff --git a/src/com/android/calendar/settings/ViewDetailsPreferences.kt b/src/com/android/calendar/settings/ViewDetailsPreferences.kt new file mode 100644 index 000000000..d3894f51b --- /dev/null +++ b/src/com/android/calendar/settings/ViewDetailsPreferences.kt @@ -0,0 +1,169 @@ +/* + * Copyright (C) 2020 Dominik Schürmann + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.android.calendar.settings + +import android.app.Activity +import android.content.Context +import android.content.SharedPreferences +import android.content.res.Configuration +import android.os.Bundle +import androidx.preference.* +import com.android.calendar.Utils +import com.android.calendar.Utils.SHARED_PREFS_NAME +import java.util.* +import ws.xsoh.etar.R + + +class ViewDetailsPreferences : PreferenceFragmentCompat() { + + private val mLandscapeConf = PreferenceConfiguration(LANDSCAPE_PREFS) + private val mPortraitConf = PreferenceConfiguration(PORTRAIT_PREFS) + + enum class TimeVisibility(val value: Int) { + SHOW_NONE(0), + SHOW_START_TIME(1), + SHOW_START_AND_END_TIME(2), + SHOW_START_TIME_AND_DURATION(3), + SHOW_TIME_RANGE_BELOW(4) + } + + override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { + preferenceManager.sharedPreferencesName = GeneralPreferences.SHARED_PREFS_NAME + + setPreferencesFromResource(R.xml.view_details_preferences, rootKey) + + mLandscapeConf.onCreate(preferenceScreen, activity) + mPortraitConf.onCreate(preferenceScreen, activity) + } + + private class PreferenceKeys internal constructor(val KEY_DISPLAY_TIME: String, + val KEY_DISPLAY_LOCATION: String, + val KEY_MAX_NUMBER_OF_LINES: String) + + private class PreferenceConfiguration(val mKeys: PreferenceKeys) { + private var mDisplayTime: ListPreference? = null + fun onCreate(preferenceScreen: PreferenceScreen, activity: Activity?) { + mDisplayTime = preferenceScreen.findPreference(mKeys.KEY_DISPLAY_TIME) as ListPreference? + initDisplayTime(activity) + } + + private fun initDisplayTime(activity: Activity?) { + if (!Utils.getConfigBool(activity, R.bool.show_time_in_month)) { + val entries = mDisplayTime!!.entries + val newEntries = Arrays.copyOf(entries, entries.size - 1) + mDisplayTime!!.entries = newEntries + } + if (mDisplayTime!!.entry == null || mDisplayTime!!.entry.length == 0) { + mDisplayTime!!.value = getDefaultTimeToShow(activity).toString() + } + } + + } + + private class DynamicPreferences(private val mContext: Context) { + private val mPrefs: SharedPreferences = GeneralPreferences.getSharedPreferences(mContext) + + val preferenceKeys: PreferenceKeys + get() { + val orientation = mContext.resources.configuration.orientation + val landscape = orientation == Configuration.ORIENTATION_LANDSCAPE + return if (landscape) LANDSCAPE_PREFS else PORTRAIT_PREFS + } + + fun getTimeVisibility(keys: PreferenceKeys): TimeVisibility { + val visibility = mPrefs.getString(keys.KEY_DISPLAY_TIME, getDefaultTimeToShow(mContext).toString()) + return TimeVisibility.values()[visibility!!.toInt()] + } + + fun getShowLocation(keys: PreferenceKeys): Boolean { + return mPrefs.getBoolean(keys.KEY_DISPLAY_LOCATION, false) + } + + fun getMaxNumberOfLines(keys: PreferenceKeys): Int { + return mPrefs.getString(keys.KEY_MAX_NUMBER_OF_LINES, null)!!.toInt() + } + + } + + class Preferences { + val TIME_VISIBILITY: TimeVisibility + val LOCATION_VISIBILITY: Boolean + val MAX_LINES: Int + + constructor(context: Context) { + val prefs = DynamicPreferences(context) + val keys = prefs.preferenceKeys + TIME_VISIBILITY = prefs.getTimeVisibility(keys) + LOCATION_VISIBILITY = prefs.getShowLocation(keys) + MAX_LINES = prefs.getMaxNumberOfLines(keys) + } + + private constructor(prefs: Preferences) { + TIME_VISIBILITY = TimeVisibility.SHOW_NONE + LOCATION_VISIBILITY = prefs.LOCATION_VISIBILITY + MAX_LINES = prefs.MAX_LINES + } + + fun hideTime(): Preferences { + return if (TIME_VISIBILITY == TimeVisibility.SHOW_TIME_RANGE_BELOW) { + Preferences(this) + } else this + } + + val isTimeVisible: Boolean + get() = TIME_VISIBILITY != TimeVisibility.SHOW_NONE + + val isTimeShownBelow: Boolean + get() = TIME_VISIBILITY == TimeVisibility.SHOW_TIME_RANGE_BELOW + + val isStartTimeVisible: Boolean + get() = TIME_VISIBILITY != TimeVisibility.SHOW_NONE + + val isEndTimeVisible: Boolean + get() = TIME_VISIBILITY == TimeVisibility.SHOW_START_AND_END_TIME || + TIME_VISIBILITY == TimeVisibility.SHOW_TIME_RANGE_BELOW + + val isDurationVisible: Boolean + get() = TIME_VISIBILITY == TimeVisibility.SHOW_START_TIME_AND_DURATION + } + + companion object { + private const val KEY_DISPLAY_TIME_V_PREF = "pref_display_time_vertical" + private const val KEY_DISPLAY_TIME_H_PREF = "pref_display_time_horizontal" + private const val KEY_DISPLAY_LOCATION_V_PREF = "pref_display_location_vertical" + private const val KEY_DISPLAY_LOCATION_H_PREF = "pref_display_location_horizontal" + private const val KEY_MAX_NUMBER_OF_LINES_V_PREF = "pref_number_of_lines_vertical" + private const val KEY_MAX_NUMBER_OF_LINES_H_PREF = "pref_number_of_lines_horizontal" + + private val LANDSCAPE_PREFS = PreferenceKeys(KEY_DISPLAY_TIME_H_PREF, KEY_DISPLAY_LOCATION_H_PREF, KEY_MAX_NUMBER_OF_LINES_H_PREF) + private val PORTRAIT_PREFS = PreferenceKeys(KEY_DISPLAY_TIME_V_PREF, KEY_DISPLAY_LOCATION_V_PREF, KEY_MAX_NUMBER_OF_LINES_V_PREF) + + protected fun getDefaultTimeToShow(context: Context?): Int { + return if (Utils.getConfigBool(context, R.bool.show_time_in_month)) TimeVisibility.SHOW_TIME_RANGE_BELOW.value else TimeVisibility.SHOW_NONE.value + } + + fun getPreferences(context: Context?): Preferences? { + return Preferences(context!!) + } + + fun setDefaultValues(context: Context?) { + PreferenceManager.setDefaultValues(context, SHARED_PREFS_NAME, Context.MODE_PRIVATE, + R.xml.view_details_preferences, true) + } + } +} \ No newline at end of file -- GitLab From c48e5cb56ffa2665bd181437f666d873e786e7d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Wed, 8 Jan 2020 22:09:23 +0100 Subject: [PATCH 54/95] Remove old preference classes and fix references --- AndroidManifest.xml | 5 - res/menu/calendar_view.xml | 4 - res/xml/general_preferences.xml | 144 ----- .../general_preferences_nougat_and_less.xml | 14 + res/xml/general_preferences_oreo_and_up.xml | 14 + res/xml/other_preferences.xml | 56 -- .../android/calendar/AboutPreferences.java | 44 -- .../android/calendar/AllInOneActivity.java | 23 +- .../android/calendar/CalendarApplication.java | 9 +- .../android/calendar/CalendarBackupAgent.java | 2 + .../android/calendar/CalendarController.java | 20 +- .../android/calendar/CalendarEventModel.java | 3 +- .../calendar/CalendarSettingsActivity.java | 204 ------- src/com/android/calendar/DayView.java | 7 +- src/com/android/calendar/Event.java | 4 +- .../android/calendar/EventInfoFragment.java | 3 +- .../android/calendar/GeneralPreferences.java | 527 ------------------ .../android/calendar/OtherPreferences.java | 248 --------- .../calendar/QuickResponseSettings.java | 102 ---- src/com/android/calendar/SearchActivity.java | 3 - src/com/android/calendar/Utils.java | 46 +- .../calendar/ViewDetailsPreferences.java | 170 ------ .../calendar/agenda/AgendaFragment.java | 4 +- .../android/calendar/alerts/AlertService.java | 75 +-- .../event/CreateEventDialogFragment.java | 2 +- .../android/calendar/event/EditEventView.java | 4 +- .../calendar/month/MonthWeekEventsView.java | 4 +- .../SelectCalendarsSyncAdapter.java | 282 ---------- .../SelectCalendarsSyncFragment.java | 217 -------- ...ctSyncedCalendarsMultiAccountActivity.java | 216 ------- ...ectSyncedCalendarsMultiAccountAdapter.java | 460 --------------- .../SelectVisibleCalendarsActivity.java | 129 ----- .../SelectVisibleCalendarsFragment.java | 3 + .../calendar/settings/GeneralPreferences.kt | 73 ++- .../calendar/settings/SettingsActivity.kt | 13 +- .../settings/ViewDetailsPreferences.kt | 9 +- 36 files changed, 175 insertions(+), 2968 deletions(-) delete mode 100644 res/xml/general_preferences.xml delete mode 100644 res/xml/other_preferences.xml delete mode 100644 src/com/android/calendar/AboutPreferences.java delete mode 100644 src/com/android/calendar/CalendarSettingsActivity.java delete mode 100644 src/com/android/calendar/GeneralPreferences.java delete mode 100644 src/com/android/calendar/OtherPreferences.java delete mode 100644 src/com/android/calendar/QuickResponseSettings.java delete mode 100644 src/com/android/calendar/ViewDetailsPreferences.java delete mode 100644 src/com/android/calendar/selectcalendars/SelectCalendarsSyncAdapter.java delete mode 100644 src/com/android/calendar/selectcalendars/SelectCalendarsSyncFragment.java delete mode 100644 src/com/android/calendar/selectcalendars/SelectSyncedCalendarsMultiAccountActivity.java delete mode 100644 src/com/android/calendar/selectcalendars/SelectSyncedCalendarsMultiAccountAdapter.java delete mode 100644 src/com/android/calendar/selectcalendars/SelectVisibleCalendarsActivity.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 0f8e2d0ae..5929d6432 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -149,11 +149,6 @@ android:label="@string/select_synced_calendars_title" android:theme="@style/Base.CalendarAppThemeWithActionBar" /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/xml/general_preferences_nougat_and_less.xml b/res/xml/general_preferences_nougat_and_less.xml index edeecb192..c9b7d85c9 100644 --- a/res/xml/general_preferences_nougat_and_less.xml +++ b/res/xml/general_preferences_nougat_and_less.xml @@ -140,5 +140,19 @@ app:title="@string/quick_response_settings" app:summary="@string/quick_response_settings_summary" /> + + + + + diff --git a/res/xml/general_preferences_oreo_and_up.xml b/res/xml/general_preferences_oreo_and_up.xml index b7bb5c084..2719a2d5c 100644 --- a/res/xml/general_preferences_oreo_and_up.xml +++ b/res/xml/general_preferences_oreo_and_up.xml @@ -124,5 +124,19 @@ app:title="@string/quick_response_settings" app:summary="@string/quick_response_settings_summary" /> + + + + + diff --git a/res/xml/other_preferences.xml b/res/xml/other_preferences.xml deleted file mode 100644 index 411643e94..000000000 --- a/res/xml/other_preferences.xml +++ /dev/null @@ -1,56 +0,0 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/com/android/calendar/AboutPreferences.java b/src/com/android/calendar/AboutPreferences.java deleted file mode 100644 index 2b35c5a4c..000000000 --- a/src/com/android/calendar/AboutPreferences.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.calendar; - -import android.app.Activity; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager.NameNotFoundException; -import android.os.Bundle; -import android.preference.PreferenceFragment; - -import ws.xsoh.etar.R; - -public class AboutPreferences extends PreferenceFragment { - private static final String BUILD_VERSION = "build_version"; - - @Override - public void onCreate(Bundle icicle) { - super.onCreate(icicle); - addPreferencesFromResource(R.xml.about_preferences); - - final Activity activity = getActivity(); - try { - final PackageInfo packageInfo = - activity.getPackageManager().getPackageInfo(activity.getPackageName(), 0); - findPreference(BUILD_VERSION).setSummary(packageInfo.versionName); - } catch (NameNotFoundException e) { - findPreference(BUILD_VERSION).setSummary("?"); - } - } -} \ No newline at end of file diff --git a/src/com/android/calendar/AllInOneActivity.java b/src/com/android/calendar/AllInOneActivity.java index fa3ac62f2..cd596f055 100644 --- a/src/com/android/calendar/AllInOneActivity.java +++ b/src/com/android/calendar/AllInOneActivity.java @@ -41,12 +41,14 @@ import android.os.Build; import android.os.Bundle; import android.os.Environment; import android.os.Handler; -import android.preference.PreferenceActivity; import android.provider.CalendarContract; import android.provider.CalendarContract.Attendees; import android.provider.CalendarContract.Events; import com.android.calendar.settings.SettingsActivity; +import com.android.calendar.settings.GeneralPreferences; +import com.android.calendar.settings.SettingsActivityKt; +import com.android.calendar.settings.ViewDetailsPreferences; import com.google.android.material.floatingactionbutton.FloatingActionButton; import com.google.android.material.navigation.NavigationView; import androidx.core.app.ActivityCompat; @@ -250,9 +252,7 @@ public class AllInOneActivity extends AbstractCalendarActivity implements EventH @Override protected void onCreate(Bundle icicle) { - if (Utils.getSharedPreference(this, OtherPreferences.KEY_OTHER_1, false)) { - setTheme(R.style.CalendarTheme_WithActionBarWallpaper); - } + setTheme(R.style.CalendarTheme_WithActionBarWallpaper); super.onCreate(icicle); dynamicTheme.onCreate(this); @@ -372,7 +372,7 @@ public class AllInOneActivity extends AbstractCalendarActivity implements EventH initFragments(timeMillis, viewType, icicle); // Listen for changes that would require this to be refreshed - SharedPreferences prefs = GeneralPreferences.getSharedPreferences(this); + SharedPreferences prefs = GeneralPreferences.Companion.getSharedPreferences(this); prefs.registerOnSharedPreferenceChangeListener(this); mContentResolver = getContentResolver(); @@ -628,7 +628,7 @@ public class AllInOneActivity extends AbstractCalendarActivity implements EventH mContentResolver.unregisterContentObserver(mObserver); if (isFinishing()) { // Stop listening for changes that would require this to be refreshed - SharedPreferences prefs = GeneralPreferences.getSharedPreferences(this); + SharedPreferences prefs = GeneralPreferences.Companion.getSharedPreferences(this); prefs.unregisterOnSharedPreferenceChangeListener(this); } // FRAG_TODO save highlighted days of the week; @@ -667,7 +667,7 @@ public class AllInOneActivity extends AbstractCalendarActivity implements EventH protected void onDestroy() { super.onDestroy(); - SharedPreferences prefs = GeneralPreferences.getSharedPreferences(this); + SharedPreferences prefs = GeneralPreferences.Companion.getSharedPreferences(this); prefs.unregisterOnSharedPreferenceChangeListener(this); mController.deregisterAllEventHandlers(); @@ -729,7 +729,7 @@ public class AllInOneActivity extends AbstractCalendarActivity implements EventH EventInfo info = null; if (viewType == ViewType.EDIT) { - mPreviousView = GeneralPreferences.getSharedPreferences(this).getInt( + mPreviousView = GeneralPreferences.Companion.getSharedPreferences(this).getInt( GeneralPreferences.KEY_START_VIEW, GeneralPreferences.DEFAULT_START_VIEW); long eventId = -1; @@ -913,8 +913,7 @@ public class AllInOneActivity extends AbstractCalendarActivity implements EventH ImportActivity.pickImportFile(this); } else if (itemId == R.id.action_view_settings) { Intent intent = new Intent(this, SettingsActivity.class); - intent.putExtra(PreferenceActivity.EXTRA_SHOW_FRAGMENT, ViewDetailsPreferences.class.getName()); - intent.putExtra( PreferenceActivity.EXTRA_NO_HEADERS, true ); + intent.putExtra(SettingsActivityKt.EXTRA_SHOW_FRAGMENT, ViewDetailsPreferences.class.getName()); startActivity(intent); } else { return mExtensions.handleItemSelected(item, this); @@ -947,10 +946,6 @@ public class AllInOneActivity extends AbstractCalendarActivity implements EventH mController.sendEvent(this, EventType.GO_TO, null, null, -1, ViewType.AGENDA); } break; - case R.id.action_select_visible_calendars: - mController.sendEvent(this, EventType.LAUNCH_SELECT_VISIBLE_CALENDARS, null, null, - 0, 0); - break; case R.id.action_settings: mController.sendEvent(this, EventType.LAUNCH_SETTINGS, null, null, 0, 0); break; diff --git a/src/com/android/calendar/CalendarApplication.java b/src/com/android/calendar/CalendarApplication.java index 57c4c9bcd..1260c11a3 100644 --- a/src/com/android/calendar/CalendarApplication.java +++ b/src/com/android/calendar/CalendarApplication.java @@ -19,6 +19,9 @@ package com.android.calendar; import android.app.Application; import android.content.SharedPreferences; +import com.android.calendar.settings.GeneralPreferences; +import com.android.calendar.settings.ViewDetailsPreferences; + public class CalendarApplication extends Application { @Override public void onCreate() { @@ -32,10 +35,10 @@ public class CalendarApplication extends Application { */ final int SHARED_PREFS_VERSION = 1; final String VERSION_KEY = "spv"; - SharedPreferences preferences = GeneralPreferences.getSharedPreferences(this); + SharedPreferences preferences = GeneralPreferences.Companion.getSharedPreferences(this); if (preferences.getInt(VERSION_KEY, 0) != SHARED_PREFS_VERSION) { - GeneralPreferences.setDefaultValues(this); - ViewDetailsPreferences.setDefaultValues(this); + GeneralPreferences.Companion.setDefaultValues(this); + ViewDetailsPreferences.Companion.setDefaultValues(this); preferences.edit().putInt(VERSION_KEY, SHARED_PREFS_VERSION).apply(); } diff --git a/src/com/android/calendar/CalendarBackupAgent.java b/src/com/android/calendar/CalendarBackupAgent.java index 0e9f9d72c..82f53a5d0 100644 --- a/src/com/android/calendar/CalendarBackupAgent.java +++ b/src/com/android/calendar/CalendarBackupAgent.java @@ -23,6 +23,8 @@ import android.content.Context; import android.content.SharedPreferences.Editor; import android.os.ParcelFileDescriptor; +import com.android.calendar.settings.GeneralPreferences; + import java.io.IOException; public class CalendarBackupAgent extends BackupAgentHelper diff --git a/src/com/android/calendar/CalendarController.java b/src/com/android/calendar/CalendarController.java index 234885071..68422ee25 100644 --- a/src/com/android/calendar/CalendarController.java +++ b/src/com/android/calendar/CalendarController.java @@ -36,7 +36,7 @@ import android.util.Log; import android.util.Pair; import com.android.calendar.event.EditEventActivity; -import com.android.calendar.selectcalendars.SelectVisibleCalendarsActivity; +import com.android.calendar.settings.GeneralPreferences; import com.android.calendar.settings.SettingsActivity; import java.lang.ref.WeakReference; @@ -415,12 +415,6 @@ public class CalendarController { return; } - // Launch Calendar Visible Selector - if (event.eventType == EventType.LAUNCH_SELECT_VISIBLE_CALENDARS) { - launchSelectVisibleCalendars(); - return; - } - // Create/View/Edit/Delete Event long endTime = (event.endTime == null) ? -1 : event.endTime.toMillis(false); if (event.eventType == EventType.CREATE_EVENT) { @@ -556,13 +550,6 @@ public class CalendarController { return mPreviousViewType; } - private void launchSelectVisibleCalendars() { - Intent intent = new Intent(Intent.ACTION_VIEW); - intent.setClass(mContext, SelectVisibleCalendarsActivity.class); - intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_SINGLE_TOP); - mContext.startActivity(intent); - } - private void launchSettings() { Intent intent = new Intent(Intent.ACTION_VIEW); intent.setClass(mContext, SettingsActivity.class); @@ -676,8 +663,6 @@ public class CalendarController { tmp = "Edit event"; } else if ((eventInfo.eventType & EventType.DELETE_EVENT) != 0) { tmp = "Delete event"; - } else if ((eventInfo.eventType & EventType.LAUNCH_SELECT_VISIBLE_CALENDARS) != 0) { - tmp = "Launch select visible calendars"; } else if ((eventInfo.eventType & EventType.LAUNCH_SETTINGS) != 0) { tmp = "Launch settings"; } else if ((eventInfo.eventType & EventType.EVENTS_CHANGED) != 0) { @@ -737,9 +722,6 @@ public class CalendarController { // date range has changed, update the title final long UPDATE_TITLE = 1L << 10; - - // select which calendars to display - final long LAUNCH_SELECT_VISIBLE_CALENDARS = 1L << 11; } /** diff --git a/src/com/android/calendar/CalendarEventModel.java b/src/com/android/calendar/CalendarEventModel.java index 88321a1f2..b43159b0d 100644 --- a/src/com/android/calendar/CalendarEventModel.java +++ b/src/com/android/calendar/CalendarEventModel.java @@ -28,6 +28,7 @@ import android.text.util.Rfc822Token; import com.android.calendar.event.EditEventHelper; import com.android.calendar.event.EventColorCache; +import com.android.calendar.settings.GeneralPreferences; import com.android.common.Rfc822Validator; import java.io.Serializable; @@ -129,7 +130,7 @@ public class CalendarEventModel implements Serializable { this(); mTimezone = Utils.getTimeZone(context, null); - SharedPreferences prefs = GeneralPreferences.getSharedPreferences(context); + SharedPreferences prefs = GeneralPreferences.Companion.getSharedPreferences(context); String defaultReminder = prefs.getString( GeneralPreferences.KEY_DEFAULT_REMINDER, GeneralPreferences.NO_REMINDER_STRING); diff --git a/src/com/android/calendar/CalendarSettingsActivity.java b/src/com/android/calendar/CalendarSettingsActivity.java deleted file mode 100644 index 85d61cba9..000000000 --- a/src/com/android/calendar/CalendarSettingsActivity.java +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.calendar; - -import android.accounts.Account; -import android.accounts.AccountManager; -import android.app.ActionBar; -import android.content.ContentResolver; -import android.content.Context; -import android.content.Intent; -import android.os.Build; -import android.os.Bundle; -import android.os.Handler; -import android.preference.PreferenceActivity; -import android.provider.CalendarContract; -import android.provider.CalendarContract.Calendars; -import android.provider.Settings; -import androidx.appcompat.widget.AppCompatCheckBox; -import androidx.appcompat.widget.AppCompatCheckedTextView; -import androidx.appcompat.widget.AppCompatEditText; -import androidx.appcompat.widget.AppCompatRadioButton; -import androidx.appcompat.widget.AppCompatSpinner; -import androidx.appcompat.widget.Toolbar; -import android.text.format.DateUtils; -import android.util.AttributeSet; -import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.widget.LinearLayout; - -import com.android.calendar.selectcalendars.SelectCalendarsSyncFragment; - -import java.util.List; - -import ws.xsoh.etar.R; - -public class CalendarSettingsActivity extends PreferenceActivity { - private static final int CHECK_ACCOUNTS_DELAY = 3000; - private Account[] mAccounts; - Runnable mCheckAccounts = new Runnable() { - @Override - public void run() { - Account[] accounts = AccountManager.get(CalendarSettingsActivity.this).getAccounts(); - if (accounts != null && !accounts.equals(mAccounts)) { - invalidateHeaders(); - } - } - }; - private Handler mHandler = new Handler(); - private boolean mHideMenuButtons = false; - private final DynamicTheme dynamicTheme = new DynamicTheme(); - - @Override - protected void onCreate(Bundle savedInstanceState) { - dynamicTheme.onCreate(this); - super.onCreate(savedInstanceState); - - LinearLayout root = (LinearLayout) findViewById(android.R.id.list).getParent().getParent().getParent(); - Toolbar bar = (Toolbar) LayoutInflater.from(this).inflate(R.layout.app_bar, root, false); - root.addView(bar, 0); // insert at top - bar.setNavigationIcon(R.drawable.ic_arrow_back); - bar.setTitle(getTitle()); - bar.setNavigationOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - finish(); - } - }); - } - - @Override - public View onCreateView(String name, Context context, AttributeSet attrs) { - // Allow super to try and create a view first - final View result = super.onCreateView(name, context, attrs); - if (result != null) { - return result; - } - - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { - // If we're running pre-L, we need to 'inject' our tint aware Views in place of the - // standard framework versions - switch (name) { - case "EditText": - return new AppCompatEditText(this, attrs); - case "Spinner": - return new AppCompatSpinner(this, attrs); - case "CheckBox": - return new AppCompatCheckBox(this, attrs); - case "RadioButton": - return new AppCompatRadioButton(this, attrs); - case "CheckedTextView": - return new AppCompatCheckedTextView(this, attrs); - } - } - return null; - } - - @Override - public void onBuildHeaders(List

target) { - loadHeadersFromResource(R.xml.calendar_settings_headers, target); - - Account[] accounts = AccountManager.get(this).getAccounts(); - if (accounts != null) { - int length = accounts.length; - for (int i = 0; i < length; i++) { - Account acct = accounts[i]; - if (ContentResolver.getIsSyncable(acct, CalendarContract.AUTHORITY) > 0) { - Header accountHeader = new Header(); - accountHeader.title = acct.name; - accountHeader.fragment = - "com.android.calendar.selectcalendars.SelectCalendarsSyncFragment"; - Bundle args = new Bundle(); - args.putString(Calendars.ACCOUNT_NAME, acct.name); - args.putString(Calendars.ACCOUNT_TYPE, acct.type); - accountHeader.fragmentArguments = args; - target.add(1, accountHeader); - } - } - } - mAccounts = accounts; - if (Utils.getTardis() + DateUtils.MINUTE_IN_MILLIS > System.currentTimeMillis()) { - Header tardisHeader = new Header(); - tardisHeader.title = getString(R.string.preferences_experimental_category); - tardisHeader.fragment = "com.android.calendar.OtherPreferences"; - target.add(tardisHeader); - } - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - if (item.getItemId() == android.R.id.home) { - finish(); - return true; - } else if (item.getItemId() == R.id.action_add_account) { - Intent nextIntent = new Intent(Settings.ACTION_ADD_ACCOUNT); - final String[] array = { "com.android.calendar" }; - nextIntent.putExtra(Settings.EXTRA_AUTHORITIES, array); - nextIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); - startActivity(nextIntent); - return true; - } - return super.onOptionsItemSelected(item); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - if (!mHideMenuButtons) { - getMenuInflater().inflate(R.menu.settings_title_bar, menu); - } - if (getActionBar() != null){ - getActionBar().setDisplayOptions(ActionBar.DISPLAY_HOME_AS_UP, ActionBar.DISPLAY_HOME_AS_UP); - } - return true; - } - - @Override - public void onResume() { - if (mHandler != null) { - mHandler.postDelayed(mCheckAccounts, CHECK_ACCOUNTS_DELAY); - } - super.onResume(); - dynamicTheme.onResume(this); - } - - @Override - public void onPause() { - if (mHandler != null) { - mHandler.removeCallbacks(mCheckAccounts); - } - super.onPause(); - } - - protected boolean isValidFragment(String fragmentName) { - return GeneralPreferences.class.getName().equals(fragmentName) - || SelectCalendarsSyncFragment.class.getName().equals(fragmentName) - || OtherPreferences.class.getName().equals(fragmentName) - || AboutPreferences.class.getName().equals(fragmentName) - || QuickResponseSettings.class.getName().equals(fragmentName) - || ViewDetailsPreferences.class.getName().equals(fragmentName); - } - - public void hideMenuButtons() { - mHideMenuButtons = true; - } - - public void restartActivity() { - recreate(); - } -} diff --git a/src/com/android/calendar/DayView.java b/src/com/android/calendar/DayView.java index a00fb9d32..aba6a5e4b 100644 --- a/src/com/android/calendar/DayView.java +++ b/src/com/android/calendar/DayView.java @@ -83,6 +83,7 @@ import android.widget.ViewSwitcher; import com.android.calendar.CalendarController.EventType; import com.android.calendar.CalendarController.ViewType; +import com.android.calendar.settings.GeneralPreferences; import java.util.ArrayList; import java.util.Arrays; @@ -923,11 +924,7 @@ public class DayView extends View implements View.OnCreateContextMenuListener, public void handleOnResume() { initAccessibilityVariables(); - if(Utils.getSharedPreference(mContext, OtherPreferences.KEY_OTHER_1, false)) { - mFutureBgColor = 0; - } else { - mFutureBgColor = mFutureBgColorRes; - } + mFutureBgColor = mFutureBgColorRes; mIs24HourFormat = DateFormat.is24HourFormat(mContext); mHourStrs = mIs24HourFormat ? CalendarData.s24Hours : CalendarData.s12Hours; mFirstDayOfWeek = Utils.getFirstDayOfWeek(mContext); diff --git a/src/com/android/calendar/Event.java b/src/com/android/calendar/Event.java index 182d66257..8f59a244b 100644 --- a/src/com/android/calendar/Event.java +++ b/src/com/android/calendar/Event.java @@ -36,6 +36,8 @@ import android.text.TextUtils; import android.text.format.DateUtils; import android.util.Log; +import com.android.calendar.settings.GeneralPreferences; + import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; @@ -202,7 +204,7 @@ public class Event implements Cloneable { // required for correctness, it just adds a nice touch. // Respect the preference to show/hide declined events - SharedPreferences prefs = GeneralPreferences.getSharedPreferences(context); + SharedPreferences prefs = GeneralPreferences.Companion.getSharedPreferences(context); boolean hideDeclined = prefs.getBoolean(GeneralPreferences.KEY_HIDE_DECLINED, false); diff --git a/src/com/android/calendar/EventInfoFragment.java b/src/com/android/calendar/EventInfoFragment.java index 6087996df..29a8881b0 100644 --- a/src/com/android/calendar/EventInfoFragment.java +++ b/src/com/android/calendar/EventInfoFragment.java @@ -106,6 +106,7 @@ import com.android.calendar.icalendar.IcalendarUtils; import com.android.calendar.icalendar.Organizer; import com.android.calendar.icalendar.VCalendar; import com.android.calendar.icalendar.VEvent; +import com.android.calendar.settings.GeneralPreferences; import com.android.calendarcommon2.DateException; import com.android.calendarcommon2.Duration; import com.android.calendarcommon2.EventRecurrence; @@ -881,7 +882,7 @@ public class EventInfoFragment extends DialogFragment implements OnCheckedChange // Set reminders variables - SharedPreferences prefs = GeneralPreferences.getSharedPreferences(mActivity); + SharedPreferences prefs = GeneralPreferences.Companion.getSharedPreferences(mActivity); String defaultReminderString = prefs.getString( GeneralPreferences.KEY_DEFAULT_REMINDER, GeneralPreferences.NO_REMINDER_STRING); mDefaultReminderMinutes = Integer.parseInt(defaultReminderString); diff --git a/src/com/android/calendar/GeneralPreferences.java b/src/com/android/calendar/GeneralPreferences.java deleted file mode 100644 index f93e5558e..000000000 --- a/src/com/android/calendar/GeneralPreferences.java +++ /dev/null @@ -1,527 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.calendar; - -import android.app.Activity; -import android.app.FragmentManager; -import android.app.backup.BackupManager; -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.content.SharedPreferences.Editor; -import android.content.SharedPreferences.OnSharedPreferenceChangeListener; -import android.media.Ringtone; -import android.media.RingtoneManager; -import android.net.Uri; -import android.os.Bundle; -import android.os.Vibrator; -import android.preference.CheckBoxPreference; -import android.preference.ListPreference; -import android.preference.Preference; -import android.preference.Preference.OnPreferenceChangeListener; -import android.preference.Preference.OnPreferenceClickListener; -import android.preference.PreferenceCategory; -import android.preference.PreferenceFragment; -import android.preference.PreferenceManager; -import android.preference.PreferenceScreen; -import android.preference.RingtonePreference; -import android.provider.CalendarContract; -import android.provider.CalendarContract.CalendarCache; -import android.provider.SearchRecentSuggestions; -import android.provider.Settings; -import android.text.TextUtils; -import android.text.format.Time; -import android.util.SparseIntArray; -import android.widget.Toast; - -import com.android.calendar.alerts.AlertReceiver; -import com.android.calendar.event.EventViewUtils; -import com.android.colorpicker.ColorPickerDialog; -import com.android.colorpicker.ColorPickerSwatch; -import com.android.timezonepicker.TimeZoneInfo; -import com.android.timezonepicker.TimeZonePickerDialog; -import com.android.timezonepicker.TimeZonePickerDialog.OnTimeZoneSetListener; -import com.android.timezonepicker.TimeZonePickerUtils; - -import ws.xsoh.etar.R; - -public class GeneralPreferences extends PreferenceFragment implements - OnSharedPreferenceChangeListener, OnPreferenceChangeListener, OnTimeZoneSetListener { - // Preference keys - public static final String KEY_THEME_PREF = "pref_theme"; - public static final String KEY_COLOR_PREF = "pref_color"; - public static final String KEY_DEFAULT_START = "preferences_default_start"; - public static final String KEY_HIDE_DECLINED = "preferences_hide_declined"; - public static final String KEY_WEEK_START_DAY = "preferences_week_start_day"; - public static final String KEY_SHOW_WEEK_NUM = "preferences_show_week_num"; - public static final String KEY_DAYS_PER_WEEK = "preferences_days_per_week"; - public static final String KEY_MDAYS_PER_WEEK = "preferences_mdays_per_week"; - public static final String KEY_SKIP_SETUP = "preferences_skip_setup"; - public static final String KEY_CLEAR_SEARCH_HISTORY = "preferences_clear_search_history"; - public static final String KEY_ALERTS_CATEGORY = "preferences_alerts_category"; - public static final String KEY_ALERTS = "preferences_alerts"; - public static final String KEY_NOTIFICATION = "preferences_notification"; - public static final String KEY_ALERTS_VIBRATE = "preferences_alerts_vibrate"; - public static final String KEY_ALERTS_RINGTONE = "preferences_alerts_ringtone"; - public static final String KEY_ALERTS_POPUP = "preferences_alerts_popup"; - public static final String KEY_SHOW_CONTROLS = "preferences_show_controls"; - public static final String KEY_DEFAULT_REMINDER = "preferences_default_reminder"; - public static final int NO_REMINDER = -1; - public static final String NO_REMINDER_STRING = "-1"; - public static final int REMINDER_DEFAULT_TIME = 10; // in minutes - public static final String KEY_USE_CUSTOM_SNOOZE_DELAY = "preferences_custom_snooze_delay"; - public static final String KEY_DEFAULT_SNOOZE_DELAY = "preferences_default_snooze_delay"; - public static final int SNOOZE_DELAY_DEFAULT_TIME = 5; // in minutes - public static final String KEY_DEFAULT_CELL_HEIGHT = "preferences_default_cell_height"; - public static final String KEY_VERSION = "preferences_version"; - /** Key to SharePreference for default view (CalendarController.ViewType) */ - public static final String KEY_START_VIEW = "preferred_startView"; - /** - * Key to SharePreference for default detail view (CalendarController.ViewType) - * Typically used by widget - */ - public static final String KEY_DETAILED_VIEW = "preferred_detailedView"; - public static final String KEY_DEFAULT_CALENDAR = "preference_defaultCalendar"; - - /** Key to preference for default new event duration (if provider doesn't indicate one) */ - public static final String KEY_DEFAULT_EVENT_DURATION = "preferences_default_event_duration"; - public static final String EVENT_DURATION_DEFAULT="60"; - - // These must be in sync with the array preferences_week_start_day_values - public static final String WEEK_START_DEFAULT = "-1"; - public static final String WEEK_START_SATURDAY = "7"; - public static final String WEEK_START_SUNDAY = "1"; - public static final String WEEK_START_MONDAY = "2"; - // Default preference values - public static final String DEFAULT_DEFAULT_START = "-2"; - public static final int DEFAULT_START_VIEW = CalendarController.ViewType.WEEK; - public static final int DEFAULT_DETAILED_VIEW = CalendarController.ViewType.DAY; - public static final boolean DEFAULT_SHOW_WEEK_NUM = false; - // This should match the XML file. - public static final String DEFAULT_RINGTONE = "content://settings/system/notification_sound"; - // The name of the shared preferences file. This name must be maintained for historical - // reasons, as it's what PreferenceManager assigned the first time the file was created. - static final String SHARED_PREFS_NAME = "com.android.calendar_preferences"; - static final String SHARED_PREFS_NAME_NO_BACKUP = "com.android.calendar_preferences_no_backup"; - static final String KEY_HOME_TZ_ENABLED = "preferences_home_tz_enabled"; - static final String KEY_HOME_TZ = "preferences_home_tz"; - private static final String FRAG_TAG_TIME_ZONE_PICKER = "TimeZonePicker"; - - CheckBoxPreference mAlert; - Preference mNotification; - CheckBoxPreference mVibrate; - RingtonePreference mRingtone; - CheckBoxPreference mPopup; - CheckBoxPreference mUseHomeTZ; - CheckBoxPreference mHideDeclined; - Preference mHomeTZ; - TimeZonePickerUtils mTzPickerUtils; - ListPreference mTheme; - Preference mColor; - ListPreference mWeekStart; - ListPreference mDayWeek; - ListPreference mDefaultReminder; - ListPreference mDefaultEventDuration; - ListPreference mSnoozeDelay; - ListPreference mDefaultStart; - - private String mTimeZoneId; - - // Used to retrieve the color id from the color picker - private SparseIntArray colorMap = new SparseIntArray(); - - /** Return a properly configured SharedPreferences instance */ - public static SharedPreferences getSharedPreferences(Context context) { - return context.getSharedPreferences(SHARED_PREFS_NAME, Context.MODE_PRIVATE); - } - - /** Set the default shared preferences in the proper context */ - public static void setDefaultValues(Context context) { - if (Utils.isOreoOrLater()) { - PreferenceManager.setDefaultValues(context, SHARED_PREFS_NAME, Context.MODE_PRIVATE, - R.xml.general_preferences_oreo_and_up, true); - } else { - PreferenceManager.setDefaultValues(context, SHARED_PREFS_NAME, Context.MODE_PRIVATE, - R.xml.general_preferences, true); - } - } - - @Override - public void onCreate(Bundle icicle) { - super.onCreate(icicle); - - final Activity activity = getActivity(); - - initializeColorMap(); - - // Make sure to always use the same preferences file regardless of the package name - // we're running under - final PreferenceManager preferenceManager = getPreferenceManager(); - final SharedPreferences sharedPreferences = getSharedPreferences(activity); - preferenceManager.setSharedPreferencesName(SHARED_PREFS_NAME); - - // Load the preferences from an XML resource - if (Utils.isOreoOrLater()) { - addPreferencesFromResource(R.xml.general_preferences_oreo_and_up); - } else { - addPreferencesFromResource(R.xml.general_preferences); - } - final PreferenceScreen preferenceScreen = getPreferenceScreen(); - - if (Utils.isOreoOrLater()) { - mNotification = preferenceScreen.findPreference(KEY_NOTIFICATION); - } else { - mAlert = (CheckBoxPreference) preferenceScreen.findPreference(KEY_ALERTS); - mVibrate = (CheckBoxPreference) preferenceScreen.findPreference(KEY_ALERTS_VIBRATE); - Vibrator vibrator = (Vibrator) activity.getSystemService(Context.VIBRATOR_SERVICE); - if (vibrator == null || !vibrator.hasVibrator()) { - PreferenceCategory mAlertGroup = (PreferenceCategory) preferenceScreen - .findPreference(KEY_ALERTS_CATEGORY); - mAlertGroup.removePreference(mVibrate); - } - mRingtone = (RingtonePreference) preferenceScreen.findPreference(KEY_ALERTS_RINGTONE); - String ringToneUri = Utils.getRingTonePreference(activity); - - // Set the ringToneUri to the backup-able shared pref only so that - // the Ringtone dialog will open up with the correct value. - final Editor editor = preferenceScreen.getEditor(); - editor.putString(GeneralPreferences.KEY_ALERTS_RINGTONE, ringToneUri).apply(); - - String ringtoneDisplayString = getRingtoneTitleFromUri(activity, ringToneUri); - mRingtone.setSummary(ringtoneDisplayString == null ? "" : ringtoneDisplayString); - } - - mPopup = (CheckBoxPreference) preferenceScreen.findPreference(KEY_ALERTS_POPUP); - mUseHomeTZ = (CheckBoxPreference) preferenceScreen.findPreference(KEY_HOME_TZ_ENABLED); - mTheme = (ListPreference) preferenceScreen.findPreference(KEY_THEME_PREF); - mColor = preferenceScreen.findPreference(KEY_COLOR_PREF); - mDefaultStart = (ListPreference) preferenceScreen.findPreference(KEY_DEFAULT_START); - mHideDeclined = (CheckBoxPreference) preferenceScreen.findPreference(KEY_HIDE_DECLINED); - mWeekStart = (ListPreference) preferenceScreen.findPreference(KEY_WEEK_START_DAY); - mDayWeek = (ListPreference) preferenceScreen.findPreference(KEY_DAYS_PER_WEEK); - mDefaultReminder = (ListPreference) preferenceScreen.findPreference(KEY_DEFAULT_REMINDER); - mDefaultEventDuration = (ListPreference) preferenceScreen.findPreference(KEY_DEFAULT_EVENT_DURATION); - mDefaultEventDuration.setSummary(mDefaultEventDuration.getEntry()); - mHomeTZ = preferenceScreen.findPreference(KEY_HOME_TZ); - mSnoozeDelay = (ListPreference) preferenceScreen.findPreference(KEY_DEFAULT_SNOOZE_DELAY); - buildSnoozeDelayEntries(); - mTheme.setSummary(mTheme.getEntry()); - mWeekStart.setSummary(mWeekStart.getEntry()); - mDayWeek.setSummary(mDayWeek.getEntry()); - mDefaultReminder.setSummary(mDefaultReminder.getEntry()); - mSnoozeDelay.setSummary(mSnoozeDelay.getEntry()); - mDefaultStart.setSummary(mDefaultStart.getEntry()); - - mColor.setOnPreferenceClickListener(new OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - showColorPickerDialog(); - return true; - } - }); - - // This triggers an asynchronous call to the provider to refresh the data in shared pref - mTimeZoneId = Utils.getTimeZone(activity, null); - - SharedPreferences prefs = CalendarUtils.getSharedPreferences(activity, - Utils.SHARED_PREFS_NAME); - - // Utils.getTimeZone will return the currentTimeZone instead of the one - // in the shared_pref if home time zone is disabled. So if home tz is - // off, we will explicitly read it. - if (!prefs.getBoolean(KEY_HOME_TZ_ENABLED, false)) { - mTimeZoneId = prefs.getString(KEY_HOME_TZ, Time.getCurrentTimezone()); - } - - mHomeTZ.setOnPreferenceClickListener(new OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - showTimezoneDialog(); - return true; - } - }); - - if (mTzPickerUtils == null) { - mTzPickerUtils = new TimeZonePickerUtils(getActivity()); - } - CharSequence timezoneName = mTzPickerUtils.getGmtDisplayName(getActivity(), mTimeZoneId, - System.currentTimeMillis(), false); - mHomeTZ.setSummary(timezoneName != null ? timezoneName : mTimeZoneId); - - TimeZonePickerDialog tzpd = (TimeZonePickerDialog) activity.getFragmentManager() - .findFragmentByTag(FRAG_TAG_TIME_ZONE_PICKER); - if (tzpd != null) { - tzpd.setOnTimeZoneSetListener(this); - } - - migrateOldPreferences(sharedPreferences); - - } - - private void showColorPickerDialog() { - final ColorPickerDialog colorPickerDialog = new ColorPickerDialog(); - // Retrieve current color to show it as selected - String selectedColorName = Utils.getSharedPreference(getActivity(), KEY_COLOR_PREF,"teal"); - int selectedColor = getResources().getColor(DynamicTheme.getColorId(selectedColorName)); - - colorPickerDialog.initialize(R.string.preferences_color_pick, - new int[]{ - getResources().getColor(R.color.colorPrimary), - getResources().getColor(R.color.colorBluePrimary), - getResources().getColor(R.color.colorPurplePrimary), - getResources().getColor(R.color.colorRedPrimary), - getResources().getColor(R.color.colorOrangePrimary), - getResources().getColor(R.color.colorGreenPrimary) - },selectedColor,3,2); - - colorPickerDialog.setOnColorSelectedListener(new ColorPickerSwatch.OnColorSelectedListener() { - @Override - public void onColorSelected(int colour) { - Utils.setSharedPreference(getActivity(), KEY_COLOR_PREF, DynamicTheme.getColorName(colorMap.get(colour))); - } - }); - - FragmentManager fm = this.getFragmentManager(); - colorPickerDialog.show(fm, "colorpicker"); - } - - private void initializeColorMap () { - colorMap.put(getResources().getColor(R.color.colorPrimary),R.color.colorPrimary); - colorMap.put(getResources().getColor(R.color.colorBluePrimary),R.color.colorBluePrimary); - colorMap.put(getResources().getColor(R.color.colorOrangePrimary),R.color.colorOrangePrimary); - colorMap.put(getResources().getColor(R.color.colorGreenPrimary),R.color.colorGreenPrimary); - colorMap.put(getResources().getColor(R.color.colorRedPrimary),R.color.colorRedPrimary); - colorMap.put(getResources().getColor(R.color.colorPurplePrimary),R.color.colorPurplePrimary); - } - - private void showTimezoneDialog() { - final Activity activity = getActivity(); - if (activity == null) { - return; - } - - Bundle b = new Bundle(); - b.putLong(TimeZonePickerDialog.BUNDLE_START_TIME_MILLIS, System.currentTimeMillis()); - b.putString(TimeZonePickerDialog.BUNDLE_TIME_ZONE, Utils.getTimeZone(activity, null)); - - FragmentManager fm = getActivity().getFragmentManager(); - TimeZonePickerDialog tzpd = (TimeZonePickerDialog) fm - .findFragmentByTag(FRAG_TAG_TIME_ZONE_PICKER); - if (tzpd != null) { - tzpd.dismiss(); - } - tzpd = new TimeZonePickerDialog(); - tzpd.setArguments(b); - tzpd.setOnTimeZoneSetListener(this); - tzpd.show(fm, FRAG_TAG_TIME_ZONE_PICKER); - } - - @Override - public void onStart() { - super.onStart(); - getPreferenceScreen().getSharedPreferences() - .registerOnSharedPreferenceChangeListener(this); - setPreferenceListeners(this); - } - - /** - * Sets up all the preference change listeners to use the specified - * listener. - */ - private void setPreferenceListeners(OnPreferenceChangeListener listener) { - mUseHomeTZ.setOnPreferenceChangeListener(listener); - mHomeTZ.setOnPreferenceChangeListener(listener); - mTheme.setOnPreferenceChangeListener(listener); - mColor.setOnPreferenceChangeListener(listener); - mDefaultStart.setOnPreferenceChangeListener(listener); - mWeekStart.setOnPreferenceChangeListener(listener); - mDayWeek.setOnPreferenceChangeListener(listener); - mDefaultReminder.setOnPreferenceChangeListener(listener); - mSnoozeDelay.setOnPreferenceChangeListener(listener); - mHideDeclined.setOnPreferenceChangeListener(listener); - mDefaultEventDuration.setOnPreferenceChangeListener(listener); - if (Utils.isOreoOrLater()) { - mNotification.setOnPreferenceChangeListener(listener); - } else { - mVibrate.setOnPreferenceChangeListener(listener); - mRingtone.setOnPreferenceChangeListener(listener); - } - } - - @Override - public void onStop() { - getPreferenceScreen().getSharedPreferences() - .unregisterOnSharedPreferenceChangeListener(this); - super.onStop(); - } - - @Override - public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { - Activity a = getActivity(); - if (key.equals(KEY_ALERTS)) { - - if (a != null) { - Intent intent = new Intent(); - intent.setClass(a, AlertReceiver.class); - if (mAlert.isChecked()) { - intent.setAction(AlertReceiver.ACTION_DISMISS_OLD_REMINDERS); - } else { - intent.setAction(AlertReceiver.EVENT_REMINDER_APP_ACTION); - } - a.sendBroadcast(intent); - } - } - if (a != null) { - BackupManager.dataChanged(a.getPackageName()); - } - - if (key.equals(KEY_THEME_PREF) || key.equals(KEY_COLOR_PREF)) { - ((CalendarSettingsActivity)getActivity()).restartActivity(); - } - } - - /** - * Handles time zone preference changes - */ - @Override - public boolean onPreferenceChange(Preference preference, Object newValue) { - String tz; - final Activity activity = getActivity(); - if (preference == mUseHomeTZ) { - if ((Boolean)newValue) { - tz = mTimeZoneId; - } else { - tz = CalendarCache.TIMEZONE_TYPE_AUTO; - } - Utils.setTimeZone(activity, tz); - return true; - } else if (preference == mTheme) { - mTheme.setValue((String) newValue); - mTheme.setSummary(mTheme.getEntry()); - } else if (preference == mHideDeclined) { - mHideDeclined.setChecked((Boolean) newValue); - Intent intent = new Intent(Utils.getWidgetScheduledUpdateAction(activity)); - intent.setDataAndType(CalendarContract.CONTENT_URI, Utils.APPWIDGET_DATA_TYPE); - activity.sendBroadcast(intent); - return true; - } else if (preference == mWeekStart) { - mWeekStart.setValue((String) newValue); - mWeekStart.setSummary(mWeekStart.getEntry()); - } else if (preference == mDayWeek) { - mDayWeek.setValue((String) newValue); - mDayWeek.setSummary(mDayWeek.getEntry()); - } else if (preference == mDefaultEventDuration) { - mDefaultEventDuration.setValue((String) newValue); - mDefaultEventDuration.setSummary(mDefaultEventDuration.getEntry()); - } else if (preference == mDefaultReminder) { - mDefaultReminder.setValue((String) newValue); - mDefaultReminder.setSummary(mDefaultReminder.getEntry()); - } else if (preference == mSnoozeDelay) { - mSnoozeDelay.setValue((String) newValue); - mSnoozeDelay.setSummary(mSnoozeDelay.getEntry()); - } else if (preference == mRingtone) { - if (newValue instanceof String) { - Utils.setRingTonePreference(activity, (String) newValue); - String ringtone = getRingtoneTitleFromUri(activity, (String) newValue); - mRingtone.setSummary(ringtone == null ? "" : ringtone); - } - return true; - } else if (preference == mVibrate) { - mVibrate.setChecked((Boolean) newValue); - return true; - } else if (preference == mDefaultStart) { - int i = mDefaultStart.findIndexOfValue((String) newValue); - mDefaultStart.setSummary(mDefaultStart.getEntries()[i]); - return true; - } else { - return true; - } - return false; - } - - public String getRingtoneTitleFromUri(Context context, String uri) { - if (TextUtils.isEmpty(uri)) { - return null; - } - - Ringtone ring = RingtoneManager.getRingtone(getActivity(), Uri.parse(uri)); - if (ring != null) { - return ring.getTitle(context); - } - return null; - } - - /** - * If necessary, upgrades previous versions of preferences to the current - * set of keys and values. - * @param prefs the preferences to upgrade - */ - private void migrateOldPreferences(SharedPreferences prefs) { - // If needed, migrate vibration setting from a previous version - if (!Utils.isOreoOrLater()) { - mVibrate.setChecked(Utils.getDefaultVibrate(getActivity(), prefs)); - } - } - - private void buildSnoozeDelayEntries() { - final CharSequence[] values = mSnoozeDelay.getEntryValues(); - final int count = values.length; - final CharSequence[] entries = new CharSequence[count]; - - for (int i = 0; i < count; i++) { - int value = Integer.parseInt(values[i].toString()); - entries[i] = EventViewUtils.constructReminderLabel(getActivity(), value, false); - } - - mSnoozeDelay.setEntries(entries); - } - - @Override - public boolean onPreferenceTreeClick( - PreferenceScreen preferenceScreen, Preference preference) { - final String key = preference.getKey(); - if (KEY_CLEAR_SEARCH_HISTORY.equals(key)) { - SearchRecentSuggestions suggestions = new SearchRecentSuggestions(getActivity(), - Utils.getSearchAuthority(getActivity()), - CalendarRecentSuggestionsProvider.MODE); - suggestions.clearHistory(); - Toast.makeText(getActivity(), R.string.search_history_cleared, - Toast.LENGTH_SHORT).show(); - return true; - } else if (KEY_NOTIFICATION.equals(key)) { - Intent intent = new Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS); - intent.putExtra(Settings.EXTRA_CHANNEL_ID, "alert_channel_01"); - intent.putExtra(Settings.EXTRA_APP_PACKAGE, getActivity().getPackageName()); - startActivity(intent); - return true; - } else { - return super.onPreferenceTreeClick(preferenceScreen, preference); - } - } - - @Override - public void onTimeZoneSet(TimeZoneInfo tzi) { - if (mTzPickerUtils == null) { - mTzPickerUtils = new TimeZonePickerUtils(getActivity()); - } - - final CharSequence timezoneName = mTzPickerUtils.getGmtDisplayName( - getActivity(), tzi.mTzId, System.currentTimeMillis(), false); - mHomeTZ.setSummary(timezoneName); - Utils.setTimeZone(getActivity(), tzi.mTzId); - } -} diff --git a/src/com/android/calendar/OtherPreferences.java b/src/com/android/calendar/OtherPreferences.java deleted file mode 100644 index 82e7e3e1d..000000000 --- a/src/com/android/calendar/OtherPreferences.java +++ /dev/null @@ -1,248 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.calendar; - -import android.app.Activity; -import android.app.TimePickerDialog; -import android.content.ComponentName; -import android.content.Intent; -import android.content.SharedPreferences; -import android.os.Bundle; -import android.preference.CheckBoxPreference; -import android.preference.ListPreference; -import android.preference.Preference; -import android.preference.Preference.OnPreferenceChangeListener; -import android.preference.PreferenceFragment; -import android.preference.PreferenceManager; -import android.preference.PreferenceScreen; -import android.text.format.DateFormat; -import android.text.format.Time; -import android.util.Log; -import android.widget.TimePicker; - -import ws.xsoh.etar.R; - -public class OtherPreferences extends PreferenceFragment implements OnPreferenceChangeListener { - // Must be the same keys that are used in the other_preferences.xml file. - public static final String KEY_OTHER_COPY_DB = "preferences_copy_db"; - public static final String KEY_OTHER_QUIET_HOURS = "preferences_reminders_quiet_hours"; - public static final String KEY_OTHER_REMINDERS_RESPONDED = "preferences_reminders_responded"; - public static final String KEY_OTHER_QUIET_HOURS_START = - "preferences_reminders_quiet_hours_start"; - public static final String KEY_OTHER_QUIET_HOURS_START_HOUR = - "preferences_reminders_quiet_hours_start_hour"; - public static final String KEY_OTHER_QUIET_HOURS_START_MINUTE = - "preferences_reminders_quiet_hours_start_minute"; - public static final String KEY_OTHER_QUIET_HOURS_END = - "preferences_reminders_quiet_hours_end"; - public static final String KEY_OTHER_QUIET_HOURS_END_HOUR = - "preferences_reminders_quiet_hours_end_hour"; - public static final String KEY_OTHER_QUIET_HOURS_END_MINUTE = - "preferences_reminders_quiet_hours_end_minute"; - public static final String KEY_OTHER_1 = "preferences_tardis_1"; - public static final int QUIET_HOURS_DEFAULT_START_HOUR = 22; - public static final int QUIET_HOURS_DEFAULT_START_MINUTE = 0; - public static final int QUIET_HOURS_DEFAULT_END_HOUR = 8; - public static final int QUIET_HOURS_DEFAULT_END_MINUTE = 0; - // The name of the shared preferences file. This name must be maintained for - // historical reasons, as it's what PreferenceManager assigned the first - // time the file was created. - static final String SHARED_PREFS_NAME = "com.android.calendar_preferences"; - private static final String TAG = "CalendarOtherPreferences"; - private static final int START_LISTENER = 1; - private static final int END_LISTENER = 2; - private static final String format24Hour = "%H:%M"; - private static final String format12Hour = "%I:%M%P"; - - private Preference mCopyDb; - private ListPreference mSkipReminders; - private CheckBoxPreference mQuietHours; - private Preference mQuietHoursStart; - private Preference mQuietHoursEnd; - - private TimePickerDialog mTimePickerDialog; - private TimeSetListener mQuietHoursStartListener; - private TimePickerDialog mQuietHoursStartDialog; - private TimeSetListener mQuietHoursEndListener; - private TimePickerDialog mQuietHoursEndDialog; - private boolean mIs24HourMode; - - public OtherPreferences() { - } - - @Override - public void onCreate(Bundle icicle) { - super.onCreate(icicle); - PreferenceManager manager = getPreferenceManager(); - manager.setSharedPreferencesName(SHARED_PREFS_NAME); - SharedPreferences prefs = manager.getSharedPreferences(); - - addPreferencesFromResource(R.xml.other_preferences); - mCopyDb = findPreference(KEY_OTHER_COPY_DB); - mSkipReminders = (ListPreference) findPreference(KEY_OTHER_REMINDERS_RESPONDED); - String skipPreferencesValue = null; - if (mSkipReminders != null) { - skipPreferencesValue = mSkipReminders.getValue(); - mSkipReminders.setOnPreferenceChangeListener(this); - } - updateSkipRemindersSummary(skipPreferencesValue); - - Activity activity = getActivity(); - if (activity == null) { - Log.d(TAG, "Activity was null"); - } - mIs24HourMode = DateFormat.is24HourFormat(activity); - - mQuietHours = - (CheckBoxPreference) findPreference(KEY_OTHER_QUIET_HOURS); - - int startHour = prefs.getInt(KEY_OTHER_QUIET_HOURS_START_HOUR, - QUIET_HOURS_DEFAULT_START_HOUR); - int startMinute = prefs.getInt(KEY_OTHER_QUIET_HOURS_START_MINUTE, - QUIET_HOURS_DEFAULT_START_MINUTE); - mQuietHoursStart = findPreference(KEY_OTHER_QUIET_HOURS_START); - mQuietHoursStartListener = new TimeSetListener(START_LISTENER); - mQuietHoursStartDialog = new TimePickerDialog( - activity, mQuietHoursStartListener, - startHour, startMinute, mIs24HourMode); - mQuietHoursStart.setSummary(formatTime(startHour, startMinute)); - - int endHour = prefs.getInt(KEY_OTHER_QUIET_HOURS_END_HOUR, - QUIET_HOURS_DEFAULT_END_HOUR); - int endMinute = prefs.getInt(KEY_OTHER_QUIET_HOURS_END_MINUTE, - QUIET_HOURS_DEFAULT_END_MINUTE); - mQuietHoursEnd = findPreference(KEY_OTHER_QUIET_HOURS_END); - mQuietHoursEndListener = new TimeSetListener(END_LISTENER); - mQuietHoursEndDialog = new TimePickerDialog( - activity, mQuietHoursEndListener, - endHour, endMinute, mIs24HourMode); - mQuietHoursEnd.setSummary(formatTime(endHour, endMinute)); - } - - @Override - public boolean onPreferenceChange(Preference preference, Object objValue) { - final String key = preference.getKey(); - - if (KEY_OTHER_REMINDERS_RESPONDED.equals(key)) { - String value = String.valueOf(objValue); - updateSkipRemindersSummary(value); - } - - return true; - } - - @Override - public boolean onPreferenceTreeClick(PreferenceScreen screen, Preference preference) { - if (preference == mCopyDb) { - Intent intent = new Intent(Intent.ACTION_MAIN); - intent.setComponent(new ComponentName("com.android.providers.calendar", - "com.android.providers.calendar.CalendarDebugActivity")); - startActivity(intent); - } else if (preference == mQuietHoursStart) { - if (mTimePickerDialog == null) { - mTimePickerDialog = mQuietHoursStartDialog; - mTimePickerDialog.show(); - } else { - Log.v(TAG, "not null"); - } - } else if (preference == mQuietHoursEnd) { - if (mTimePickerDialog == null) { - mTimePickerDialog = mQuietHoursEndDialog; - mTimePickerDialog.show(); - } else { - Log.v(TAG, "not null"); - } - } else { - return super.onPreferenceTreeClick(screen, preference); - } - return true; - } - - /** - * @param hourOfDay the hour of the day (0-24) - * @param minute - * @return human-readable string formatted based on 24-hour mode. - */ - private String formatTime(int hourOfDay, int minute) { - Time time = new Time(); - time.hour = hourOfDay; - time.minute = minute; - - String format = mIs24HourMode? format24Hour : format12Hour; - return time.format(format); - } - - /** - * Update the summary for the SkipReminders preference. - * @param value The corresponding value of which summary to set. If null, the default summary - * will be set, and the value will be set accordingly too. - */ - private void updateSkipRemindersSummary(String value) { - if (mSkipReminders != null) { - // Default to "declined". Must match with R.array.preferences_skip_reminders_values. - int index = 0; - - CharSequence[] values = mSkipReminders.getEntryValues(); - CharSequence[] entries = mSkipReminders.getEntries(); - for(int value_i = 0; value_i < values.length; value_i++) { - if (values[value_i].equals(value)) { - index = value_i; - break; - } - } - mSkipReminders.setSummary(entries[index].toString()); - if (value == null) { - // Value was not known ahead of time, so the default value will be set. - mSkipReminders.setValue(values[index].toString()); - } - } - } - - private class TimeSetListener implements TimePickerDialog.OnTimeSetListener { - private int mListenerId; - - public TimeSetListener(int listenerId) { - mListenerId = listenerId; - } - - @Override - public void onTimeSet(TimePicker view, int hourOfDay, int minute) { - mTimePickerDialog = null; - - SharedPreferences prefs = getPreferenceManager().getSharedPreferences(); - SharedPreferences.Editor editor = prefs.edit(); - - String summary = formatTime(hourOfDay, minute); - switch (mListenerId) { - case (START_LISTENER): - mQuietHoursStart.setSummary(summary); - editor.putInt(KEY_OTHER_QUIET_HOURS_START_HOUR, hourOfDay); - editor.putInt(KEY_OTHER_QUIET_HOURS_START_MINUTE, minute); - break; - case (END_LISTENER): - mQuietHoursEnd.setSummary(summary); - editor.putInt(KEY_OTHER_QUIET_HOURS_END_HOUR, hourOfDay); - editor.putInt(KEY_OTHER_QUIET_HOURS_END_MINUTE, minute); - break; - default: - Log.d(TAG, "Set time for unknown listener: " + mListenerId); - } - - editor.commit(); - } - } -} diff --git a/src/com/android/calendar/QuickResponseSettings.java b/src/com/android/calendar/QuickResponseSettings.java deleted file mode 100644 index 912bac54e..000000000 --- a/src/com/android/calendar/QuickResponseSettings.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.calendar; - -import android.app.Activity; -import android.os.Bundle; -import android.preference.EditTextPreference; -import android.preference.Preference; -import android.preference.Preference.OnPreferenceChangeListener; -import android.preference.PreferenceFragment; -import android.preference.PreferenceScreen; -import android.util.Log; - -import java.util.Arrays; - -import ws.xsoh.etar.R; - -/** - * Fragment to facilitate editing of quick responses when emailing guests - * - */ -public class QuickResponseSettings extends PreferenceFragment implements OnPreferenceChangeListener { - private static final String TAG = "QuickResponseSettings"; - - EditTextPreference[] mEditTextPrefs; - String[] mResponses; - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - PreferenceScreen ps = getPreferenceManager().createPreferenceScreen(getActivity()); - ps.setTitle(R.string.quick_response_settings_title); - - mResponses = Utils.getQuickResponses(getActivity()); - - if (mResponses != null) { - mEditTextPrefs = new EditTextPreference[mResponses.length]; - - Arrays.sort(mResponses); - int i = 0; - for (String response : mResponses) { - EditTextPreference et = new EditTextPreference(getActivity()); - et.setDialogTitle(R.string.quick_response_settings_edit_title); - et.setTitle(response); // Display Text - et.setText(response); // Value to edit - et.setOnPreferenceChangeListener(this); - mEditTextPrefs[i++] = et; - ps.addPreference(et); - } - } else { - Log.wtf(TAG, "No responses found"); - } - setPreferenceScreen(ps); - } - - @Override - public void onAttach(Activity activity) { - super.onAttach(activity); - ((CalendarSettingsActivity) activity).hideMenuButtons(); - } - - @Override - public void onResume() { - super.onResume(); - CalendarSettingsActivity activity = (CalendarSettingsActivity) getActivity(); - if (!activity.isMultiPane()) { - activity.setTitle(R.string.quick_response_settings_title); - } - } - - // Implements OnPreferenceChangeListener - @Override - public boolean onPreferenceChange(Preference preference, Object newValue) { - for (int i = 0; i < mEditTextPrefs.length; i++) { - if (mEditTextPrefs[i].compareTo(preference) == 0) { - if (!mResponses[i].equals(newValue)) { - mResponses[i] = (String) newValue; - mEditTextPrefs[i].setTitle(mResponses[i]); - mEditTextPrefs[i].setText(mResponses[i]); - Utils.setSharedPreference(getActivity(), Utils.KEY_QUICK_RESPONSES, mResponses); - } - return true; - } - } - return false; - } -} diff --git a/src/com/android/calendar/SearchActivity.java b/src/com/android/calendar/SearchActivity.java index 52dc44f94..45a658c2a 100644 --- a/src/com/android/calendar/SearchActivity.java +++ b/src/com/android/calendar/SearchActivity.java @@ -152,9 +152,6 @@ public class SearchActivity extends AppCompatActivity implements CalendarControl } else { query = intent.getStringExtra(SearchManager.QUERY); } - if ("TARDIS".equalsIgnoreCase(query)) { - Utils.tardis(); - } initFragments(millis, query); } } diff --git a/src/com/android/calendar/Utils.java b/src/com/android/calendar/Utils.java index 11052c170..1b73dcad9 100644 --- a/src/com/android/calendar/Utils.java +++ b/src/com/android/calendar/Utils.java @@ -54,6 +54,7 @@ import android.util.Log; import com.android.calendar.CalendarController.ViewType; import com.android.calendar.CalendarEventModel.ReminderEntry; import com.android.calendar.CalendarUtils.TimeZoneUtils; +import com.android.calendar.settings.GeneralPreferences; import java.util.ArrayList; import java.util.Arrays; @@ -187,7 +188,6 @@ public class Utils { static int CONFLICT_COLOR = 0xFF000000; static boolean mMinutesLoaded = false; private static boolean mAllowWeekForDetailView = false; - private static long mTardis = 0; private static String sVersion = null; /** @@ -200,7 +200,7 @@ public class Utils { public static int getViewTypeFromIntentAndSharedPref(Activity activity) { Intent intent = activity.getIntent(); Bundle extras = intent.getExtras(); - SharedPreferences prefs = GeneralPreferences.getSharedPreferences(activity); + SharedPreferences prefs = GeneralPreferences.Companion.getSharedPreferences(activity); if (TextUtils.equals(intent.getAction(), Intent.ACTION_EDIT)) { return ViewType.EDIT; @@ -305,7 +305,7 @@ public class Utils { } public static String[] getSharedPreference(Context context, String key, String[] defaultValue) { - SharedPreferences prefs = GeneralPreferences.getSharedPreferences(context); + SharedPreferences prefs = GeneralPreferences.Companion.getSharedPreferences(context); Set ss = prefs.getStringSet(key, null); if (ss != null) { String strings[] = new String[ss.size()]; @@ -315,17 +315,17 @@ public class Utils { } public static String getSharedPreference(Context context, String key, String defaultValue) { - SharedPreferences prefs = GeneralPreferences.getSharedPreferences(context); + SharedPreferences prefs = GeneralPreferences.Companion.getSharedPreferences(context); return prefs.getString(key, defaultValue); } public static int getSharedPreference(Context context, String key, int defaultValue) { - SharedPreferences prefs = GeneralPreferences.getSharedPreferences(context); + SharedPreferences prefs = GeneralPreferences.Companion.getSharedPreferences(context); return prefs.getInt(key, defaultValue); } public static boolean getSharedPreference(Context context, String key, boolean defaultValue) { - SharedPreferences prefs = GeneralPreferences.getSharedPreferences(context); + SharedPreferences prefs = GeneralPreferences.Companion.getSharedPreferences(context); return prefs.getBoolean(key, defaultValue); } @@ -337,34 +337,26 @@ public class Utils { * @param value the value to set */ public static void setSharedPreference(Context context, String key, String value) { - SharedPreferences prefs = GeneralPreferences.getSharedPreferences(context); + SharedPreferences prefs = GeneralPreferences.Companion.getSharedPreferences(context); prefs.edit().putString(key, value).apply(); } public static void setSharedPreference(Context context, String key, String[] values) { - SharedPreferences prefs = GeneralPreferences.getSharedPreferences(context); + SharedPreferences prefs = GeneralPreferences.Companion.getSharedPreferences(context); LinkedHashSet set = new LinkedHashSet(); Collections.addAll(set, values); prefs.edit().putStringSet(key, set).apply(); } - protected static void tardis() { - mTardis = System.currentTimeMillis(); - } - - protected static long getTardis() { - return mTardis; - } - public static void setSharedPreference(Context context, String key, boolean value) { - SharedPreferences prefs = GeneralPreferences.getSharedPreferences(context); + SharedPreferences prefs = GeneralPreferences.Companion.getSharedPreferences(context); SharedPreferences.Editor editor = prefs.edit(); editor.putBoolean(key, value); editor.apply(); } static void setSharedPreference(Context context, String key, int value) { - SharedPreferences prefs = GeneralPreferences.getSharedPreferences(context); + SharedPreferences prefs = GeneralPreferences.Companion.getSharedPreferences(context); SharedPreferences.Editor editor = prefs.edit(); editor.putInt(key, value); editor.apply(); @@ -418,7 +410,7 @@ public class Utils { * @param viewId {@link CalendarController.ViewType} */ static void setDefaultView(Context context, int viewId) { - SharedPreferences prefs = GeneralPreferences.getSharedPreferences(context); + SharedPreferences prefs = GeneralPreferences.Companion.getSharedPreferences(context); SharedPreferences.Editor editor = prefs.edit(); boolean validDetailView = false; @@ -599,7 +591,7 @@ public class Utils { * @return the first day of week in android.text.format.Time */ public static int getFirstDayOfWeek(Context context) { - SharedPreferences prefs = GeneralPreferences.getSharedPreferences(context); + SharedPreferences prefs = GeneralPreferences.Companion.getSharedPreferences(context); String pref = prefs.getString( GeneralPreferences.KEY_WEEK_START_DAY, GeneralPreferences.WEEK_START_DEFAULT); @@ -625,7 +617,7 @@ public class Utils { * @return the default event length, in milliseconds */ public static long getDefaultEventDurationInMillis(Context context) { - SharedPreferences prefs = GeneralPreferences.getSharedPreferences(context); + SharedPreferences prefs = GeneralPreferences.Companion.getSharedPreferences(context); String pref = prefs.getString(GeneralPreferences.KEY_DEFAULT_EVENT_DURATION, GeneralPreferences.EVENT_DURATION_DEFAULT); final int defaultDurationInMins = Integer.parseInt(pref); @@ -670,7 +662,7 @@ public class Utils { * @return true when week number should be shown. */ public static boolean getShowWeekNumber(Context context) { - final SharedPreferences prefs = GeneralPreferences.getSharedPreferences(context); + final SharedPreferences prefs = GeneralPreferences.Companion.getSharedPreferences(context); return prefs.getBoolean( GeneralPreferences.KEY_SHOW_WEEK_NUM, GeneralPreferences.DEFAULT_SHOW_WEEK_NUM); } @@ -679,27 +671,27 @@ public class Utils { * @return true when declined events should be hidden. */ public static boolean getHideDeclinedEvents(Context context) { - final SharedPreferences prefs = GeneralPreferences.getSharedPreferences(context); + final SharedPreferences prefs = GeneralPreferences.Companion.getSharedPreferences(context); return prefs.getBoolean(GeneralPreferences.KEY_HIDE_DECLINED, false); } public static int getDaysPerWeek(Context context) { - final SharedPreferences prefs = GeneralPreferences.getSharedPreferences(context); + final SharedPreferences prefs = GeneralPreferences.Companion.getSharedPreferences(context); return Integer.valueOf(prefs.getString(GeneralPreferences.KEY_DAYS_PER_WEEK, "7")); } public static int getMDaysPerWeek(Context context) { - final SharedPreferences prefs = GeneralPreferences.getSharedPreferences(context); + final SharedPreferences prefs = GeneralPreferences.Companion.getSharedPreferences(context); return Integer.valueOf(prefs.getString(GeneralPreferences.KEY_MDAYS_PER_WEEK, "7")); } public static boolean useCustomSnoozeDelay(Context context) { - final SharedPreferences prefs = GeneralPreferences.getSharedPreferences(context); + final SharedPreferences prefs = GeneralPreferences.Companion.getSharedPreferences(context); return prefs.getBoolean(GeneralPreferences.KEY_USE_CUSTOM_SNOOZE_DELAY, false); } public static long getDefaultSnoozeDelayMs(Context context) { - final SharedPreferences prefs = GeneralPreferences.getSharedPreferences(context); + final SharedPreferences prefs = GeneralPreferences.Companion.getSharedPreferences(context); final String value = prefs.getString(GeneralPreferences.KEY_DEFAULT_SNOOZE_DELAY, null); final long intValue = value != null ? Long.valueOf(value) diff --git a/src/com/android/calendar/ViewDetailsPreferences.java b/src/com/android/calendar/ViewDetailsPreferences.java deleted file mode 100644 index ad1ef1d2a..000000000 --- a/src/com/android/calendar/ViewDetailsPreferences.java +++ /dev/null @@ -1,170 +0,0 @@ -package com.android.calendar; - -import android.app.Activity; -import android.content.Context; -import android.content.SharedPreferences; -import android.content.res.Configuration; -import android.os.Bundle; -import android.preference.ListPreference; -import android.preference.PreferenceFragment; -import android.preference.PreferenceManager; -import android.preference.PreferenceScreen; - -import java.util.Arrays; - -import ws.xsoh.etar.R; - - -public class ViewDetailsPreferences extends PreferenceFragment { - private final static String KEY_DISPLAY_TIME_V_PREF = "pref_display_time_vertical"; - private final static String KEY_DISPLAY_TIME_H_PREF = "pref_display_time_horizontal"; - private final static String KEY_DISPLAY_LOCATION_V_PREF = "pref_display_location_vertical"; - private final static String KEY_DISPLAY_LOCATION_H_PREF = "pref_display_location_horizontal"; - private final static String KEY_MAX_NUMBER_OF_LINES_V_PREF = "pref_number_of_lines_vertical"; - private final static String KEY_MAX_NUMBER_OF_LINES_H_PREF = "pref_number_of_lines_horizontal"; - private final static PreferenceKeys LANDSCAPE_PREFS = new PreferenceKeys(KEY_DISPLAY_TIME_H_PREF, KEY_DISPLAY_LOCATION_H_PREF, KEY_MAX_NUMBER_OF_LINES_H_PREF); - private final static PreferenceKeys PORTRAIT_PREFS = new PreferenceKeys(KEY_DISPLAY_TIME_V_PREF, KEY_DISPLAY_LOCATION_V_PREF, KEY_MAX_NUMBER_OF_LINES_V_PREF); - - private PreferenceConfiguration mLandscapeConf = new PreferenceConfiguration(LANDSCAPE_PREFS); - private PreferenceConfiguration mPortraitConf = new PreferenceConfiguration(PORTRAIT_PREFS); - - public enum TimeVisibility { - SHOW_NONE(0), - SHOW_START_TIME(1), - SHOW_START_AND_END_TIME(2), - SHOW_START_TIME_AND_DURATION(3), - SHOW_TIME_RANGE_BELOW(4); - private int mValue; - TimeVisibility(int value) { - mValue = value; - } - int getValue() { - return mValue; - } - } - private static class PreferenceKeys { - protected final String KEY_DISPLAY_TIME; - protected final String KEY_DISPLAY_LOCATION; - protected final String KEY_MAX_NUMBER_OF_LINES; - PreferenceKeys(String keyDisplayTime, String keyDisplayLocation, String keyMaxNumberOfLInes) { - KEY_DISPLAY_TIME = keyDisplayTime; - KEY_DISPLAY_LOCATION = keyDisplayLocation; - KEY_MAX_NUMBER_OF_LINES = keyMaxNumberOfLInes; - } - } - - protected static class PreferenceConfiguration { - private PreferenceKeys mKeys; - private ListPreference mDisplayTime; - - PreferenceConfiguration(PreferenceKeys keys) { - mKeys = keys; - } - - protected void onCreate(PreferenceScreen preferenceScreen, Activity activity) - { - mDisplayTime = (ListPreference) preferenceScreen.findPreference(mKeys.KEY_DISPLAY_TIME); - initDisplayTime(activity); - } - private void initDisplayTime(Activity activity) { - if (!Utils.getConfigBool(activity, R.bool.show_time_in_month)) { - CharSequence[] entries = mDisplayTime.getEntries(); - CharSequence[] newEntries = Arrays.copyOf(entries, entries.length-1); - mDisplayTime.setEntries(newEntries); - } - if (mDisplayTime.getEntry() == null || mDisplayTime.getEntry().length() == 0) { - mDisplayTime.setValue(getDefaultTimeToShow(activity).toString()); - } - } - } - static class DynamicPreferences { - private Context mContext; - private SharedPreferences mPrefs; - DynamicPreferences(Context context) - { - mContext = context; - mPrefs = GeneralPreferences.getSharedPreferences(context); - } - public PreferenceKeys getPreferenceKeys() { - int orientation = mContext.getResources().getConfiguration().orientation; - boolean landscape = (orientation == Configuration.ORIENTATION_LANDSCAPE); - return landscape ? LANDSCAPE_PREFS : PORTRAIT_PREFS; - } - public TimeVisibility getTimeVisibility(PreferenceKeys keys) { - String visibility = mPrefs.getString(keys.KEY_DISPLAY_TIME, getDefaultTimeToShow(mContext).toString()); - return TimeVisibility.values()[Integer.parseInt(visibility)]; - } - public boolean getShowLocation(PreferenceKeys keys) { - return mPrefs.getBoolean(keys.KEY_DISPLAY_LOCATION, false); - } - public Integer getMaxNumberOfLines(PreferenceKeys keys) { - return Integer.parseInt(mPrefs.getString(keys.KEY_MAX_NUMBER_OF_LINES, null)); - } - } - public static class Preferences { - public final TimeVisibility TIME_VISIBILITY; - public final boolean LOCATION_VISIBILITY; - public final int MAX_LINES; - - protected Preferences(Context context) { - DynamicPreferences prefs = new DynamicPreferences(context); - PreferenceKeys keys = prefs.getPreferenceKeys(); - TIME_VISIBILITY = prefs.getTimeVisibility(keys); - LOCATION_VISIBILITY = prefs.getShowLocation(keys); - MAX_LINES = prefs.getMaxNumberOfLines(keys); - } - private Preferences(Preferences prefs) { - TIME_VISIBILITY = TimeVisibility.SHOW_NONE; - LOCATION_VISIBILITY = prefs.LOCATION_VISIBILITY; - MAX_LINES = prefs.MAX_LINES; - } - public Preferences hideTime() { - if (TIME_VISIBILITY == TimeVisibility.SHOW_TIME_RANGE_BELOW) { - return new Preferences(this); - } - return this; - } - public boolean isTimeVisible() { - return TIME_VISIBILITY != TimeVisibility.SHOW_NONE; - } - public boolean isTimeShownBelow() { - return (TIME_VISIBILITY == TimeVisibility.SHOW_TIME_RANGE_BELOW); - } - public boolean isStartTimeVisible() { - return (TIME_VISIBILITY != TimeVisibility.SHOW_NONE); - } - public boolean isEndTimeVisible() { - return (TIME_VISIBILITY == TimeVisibility.SHOW_START_AND_END_TIME) || - (TIME_VISIBILITY == TimeVisibility.SHOW_TIME_RANGE_BELOW); - } - public boolean isDurationVisible() { - return (TIME_VISIBILITY == TimeVisibility.SHOW_START_TIME_AND_DURATION); - } - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - final PreferenceManager preferenceManager = getPreferenceManager(); - preferenceManager.setSharedPreferencesName(GeneralPreferences.SHARED_PREFS_NAME); - addPreferencesFromResource(R.xml.view_details_preferences); - PreferenceScreen preferenceScreen = getPreferenceScreen(); - Activity activity = getActivity(); - mLandscapeConf.onCreate(preferenceScreen, activity); - mPortraitConf.onCreate(preferenceScreen, activity); - } - - protected static Integer getDefaultTimeToShow(Context context) { - return (Utils.getConfigBool(context, R.bool.show_time_in_month)) ? - TimeVisibility.SHOW_TIME_RANGE_BELOW.getValue() : TimeVisibility.SHOW_NONE.getValue(); - } - - public static Preferences getPreferences(Context context) { - return new Preferences(context); - } - - public static void setDefaultValues(Context context) { - PreferenceManager.setDefaultValues(context, GeneralPreferences.SHARED_PREFS_NAME, Context.MODE_PRIVATE, - R.xml.view_details_preferences, true); - } -} diff --git a/src/com/android/calendar/agenda/AgendaFragment.java b/src/com/android/calendar/agenda/AgendaFragment.java index 202d7f453..e10ea655c 100644 --- a/src/com/android/calendar/agenda/AgendaFragment.java +++ b/src/com/android/calendar/agenda/AgendaFragment.java @@ -39,9 +39,9 @@ import com.android.calendar.CalendarController.EventInfo; import com.android.calendar.CalendarController.EventType; import com.android.calendar.CalendarController.ViewType; import com.android.calendar.EventInfoFragment; -import com.android.calendar.GeneralPreferences; import com.android.calendar.StickyHeaderListView; import com.android.calendar.Utils; +import com.android.calendar.settings.GeneralPreferences; import java.util.Date; @@ -211,7 +211,7 @@ public class AgendaFragment extends Fragment implements CalendarController.Event Log.v(TAG, "OnResume to " + mTime.toString()); } - SharedPreferences prefs = GeneralPreferences.getSharedPreferences( + SharedPreferences prefs = GeneralPreferences.Companion.getSharedPreferences( getActivity()); boolean hideDeclined = prefs.getBoolean( GeneralPreferences.KEY_HIDE_DECLINED, false); diff --git a/src/com/android/calendar/alerts/AlertService.java b/src/com/android/calendar/alerts/AlertService.java index e6e9121b0..ad0065d09 100644 --- a/src/com/android/calendar/alerts/AlertService.java +++ b/src/com/android/calendar/alerts/AlertService.java @@ -49,9 +49,8 @@ import android.text.format.DateUtils; import android.text.format.Time; import android.util.Log; -import com.android.calendar.GeneralPreferences; -import com.android.calendar.OtherPreferences; import com.android.calendar.Utils; +import com.android.calendar.settings.GeneralPreferences; import java.util.ArrayList; import java.util.HashMap; @@ -159,7 +158,7 @@ public class AlertService extends Service { final long currentTime = System.currentTimeMillis(); - SharedPreferences prefs = GeneralPreferences.getSharedPreferences(context); + SharedPreferences prefs = GeneralPreferences.Companion.getSharedPreferences(context); if (DEBUG) { Log.d(TAG, "Beginning updateAlertNotification"); @@ -453,40 +452,12 @@ public class AlertService extends Service { // Experimental reminder setting to only remind for events that have // been responded to with "yes" or "maybe". String skipRemindersPref = Utils.getSharedPreference(context, - OtherPreferences.KEY_OTHER_REMINDERS_RESPONDED, ""); + GeneralPreferences.KEY_OTHER_REMINDERS_RESPONDED, ""); // Skip no-response events if the "Skip Reminders" preference has the second option, // "If declined or not responded", is selected. // Note that by default, the first option will be selected, so this will be false. boolean remindRespondedOnly = skipRemindersPref.equals(context.getResources(). getStringArray(R.array.preferences_skip_reminders_values)[1]); - // Experimental reminder setting to silence reminders when they are - // during the pre-defined quiet hours. - boolean useQuietHours = Utils.getSharedPreference(context, - OtherPreferences.KEY_OTHER_QUIET_HOURS, false); - // Note that the start time may be either before or after the end time, - // depending on whether quiet hours cross through midnight. - int quietHoursStartHour = - OtherPreferences.QUIET_HOURS_DEFAULT_START_HOUR; - int quietHoursStartMinute = - OtherPreferences.QUIET_HOURS_DEFAULT_START_MINUTE; - int quietHoursEndHour = - OtherPreferences.QUIET_HOURS_DEFAULT_END_HOUR; - int quietHoursEndMinute = - OtherPreferences.QUIET_HOURS_DEFAULT_END_MINUTE; - if (useQuietHours) { - quietHoursStartHour = Utils.getSharedPreference(context, - OtherPreferences.KEY_OTHER_QUIET_HOURS_START_HOUR, - OtherPreferences.QUIET_HOURS_DEFAULT_START_HOUR); - quietHoursStartMinute = Utils.getSharedPreference(context, - OtherPreferences.KEY_OTHER_QUIET_HOURS_START_MINUTE, - OtherPreferences.QUIET_HOURS_DEFAULT_START_MINUTE); - quietHoursEndHour = Utils.getSharedPreference(context, - OtherPreferences.KEY_OTHER_QUIET_HOURS_END_HOUR, - OtherPreferences.QUIET_HOURS_DEFAULT_END_HOUR); - quietHoursEndMinute = Utils.getSharedPreference(context, - OtherPreferences.KEY_OTHER_QUIET_HOURS_END_MINUTE, - OtherPreferences.QUIET_HOURS_DEFAULT_END_MINUTE); - } Time time = new Time(); ContentResolver cr = context.getContentResolver(); @@ -510,45 +481,7 @@ public class AlertService extends Service { .withAppendedId(CalendarAlerts.CONTENT_URI, alertId); final long alarmTime = alertCursor.getLong(ALERT_INDEX_ALARM_TIME); boolean forceQuiet = false; - if (useQuietHours) { - // Quiet hours have been set. - time.set(alarmTime); - // Check whether the alarm will fire after the quiet hours - // start time and/or before the quiet hours end time. - boolean alarmAfterQuietHoursStart = - (time.hour > quietHoursStartHour || - (time.hour == quietHoursStartHour - && time.minute >= quietHoursStartMinute)); - boolean alarmBeforeQuietHoursEnd = - (time.hour < quietHoursEndHour || - (time.hour == quietHoursEndHour - && time.minute <= quietHoursEndMinute)); - // Check if quiet hours crosses through midnight, iff: - // start hour is after end hour, or - // start hour is equal to end hour, and start minute is - // after end minute. - // i.e. 22:30 - 06:45; 12:45 - 12:00 - // 01:05 - 10:30; 05:00 - 05:30 - boolean quietHoursCrossesMidnight = - quietHoursStartHour > quietHoursEndHour || - (quietHoursStartHour == quietHoursEndHour - && quietHoursStartMinute > quietHoursEndMinute); - if (quietHoursCrossesMidnight) { - // Quiet hours crosses midnight. Alarm should be quiet - // if it's after start time OR before end time. - if (alarmAfterQuietHoursStart || - alarmBeforeQuietHoursEnd) { - forceQuiet = true; - } - } else { - // Quiet hours doesn't cross midnight. Alarm should be - // quiet if it's after start time AND before end time. - if (alarmAfterQuietHoursStart && - alarmBeforeQuietHoursEnd) { - forceQuiet = true; - } - } - } + int state = alertCursor.getInt(ALERT_INDEX_STATE); final boolean allDay = alertCursor.getInt(ALERT_INDEX_ALL_DAY) != 0; diff --git a/src/com/android/calendar/event/CreateEventDialogFragment.java b/src/com/android/calendar/event/CreateEventDialogFragment.java index b8ca62adb..dbd1c28c4 100644 --- a/src/com/android/calendar/event/CreateEventDialogFragment.java +++ b/src/com/android/calendar/event/CreateEventDialogFragment.java @@ -43,8 +43,8 @@ import com.android.calendar.AsyncQueryService; import com.android.calendar.CalendarController; import com.android.calendar.CalendarController.EventType; import com.android.calendar.CalendarEventModel; -import com.android.calendar.GeneralPreferences; import com.android.calendar.Utils; +import com.android.calendar.settings.GeneralPreferences; import ws.xsoh.etar.R; diff --git a/src/com/android/calendar/event/EditEventView.java b/src/com/android/calendar/event/EditEventView.java index a8c50f323..15a1b0208 100644 --- a/src/com/android/calendar/event/EditEventView.java +++ b/src/com/android/calendar/event/EditEventView.java @@ -76,11 +76,11 @@ import com.android.calendar.CalendarEventModel.ReminderEntry; import com.android.calendar.EmailAddressAdapter; import com.android.calendar.EventInfoFragment; import com.android.calendar.EventRecurrenceFormatter; -import com.android.calendar.GeneralPreferences; import com.android.calendar.RecipientAdapter; import com.android.calendar.Utils; import com.android.calendar.event.EditEventHelper.EditDoneRunnable; import com.android.calendar.recurrencepicker.RecurrencePickerDialog; +import com.android.calendar.settings.GeneralPreferences; import com.android.calendarcommon2.EventRecurrence; import com.android.common.Rfc822InputFilter; import com.android.common.Rfc822Validator; @@ -879,7 +879,7 @@ public class EditEventView implements View.OnClickListener, DialogInterface.OnCa populateTimezone(mStartTime.normalize(true)); - SharedPreferences prefs = GeneralPreferences.getSharedPreferences(mActivity); + SharedPreferences prefs = GeneralPreferences.Companion.getSharedPreferences(mActivity); String defaultReminderString = prefs.getString( GeneralPreferences.KEY_DEFAULT_REMINDER, GeneralPreferences.NO_REMINDER_STRING); mDefaultReminderMinutes = Integer.parseInt(defaultReminderString); diff --git a/src/com/android/calendar/month/MonthWeekEventsView.java b/src/com/android/calendar/month/MonthWeekEventsView.java index 15c641d78..3bacaeac3 100644 --- a/src/com/android/calendar/month/MonthWeekEventsView.java +++ b/src/com/android/calendar/month/MonthWeekEventsView.java @@ -20,7 +20,7 @@ import com.android.calendar.DynamicTheme; import com.android.calendar.Event; import com.android.calendar.LunarUtils; import com.android.calendar.Utils; -import com.android.calendar.ViewDetailsPreferences; +import com.android.calendar.settings.ViewDetailsPreferences; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; @@ -852,7 +852,7 @@ public class MonthWeekEventsView extends SimpleWeekView { public ArrayList prepareFormattedEvents() { prepareFormattedEventsWithEventDaySpan(); ViewDetailsPreferences.Preferences preferences = - ViewDetailsPreferences.getPreferences(getContext()); + ViewDetailsPreferences.Companion.getPreferences(getContext()); preFormatEventText(preferences); setYindexInEvents(); return formatDays(mBoxBoundaries.getAvailableYSpace(), preferences); diff --git a/src/com/android/calendar/selectcalendars/SelectCalendarsSyncAdapter.java b/src/com/android/calendar/selectcalendars/SelectCalendarsSyncAdapter.java deleted file mode 100644 index e7dbcb4b7..000000000 --- a/src/com/android/calendar/selectcalendars/SelectCalendarsSyncAdapter.java +++ /dev/null @@ -1,282 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.calendar.selectcalendars; - -import android.app.FragmentManager; -import android.content.Context; -import android.content.res.Resources; -import android.database.Cursor; -import android.graphics.Rect; -import android.graphics.drawable.shapes.RectShape; -import android.provider.CalendarContract.Calendars; -import android.text.TextUtils; -import android.view.LayoutInflater; -import android.view.TouchDelegate; -import android.view.View; -import android.view.View.OnClickListener; -import android.view.ViewGroup; -import android.widget.AdapterView; -import android.widget.BaseAdapter; -import android.widget.CheckBox; -import android.widget.ListAdapter; -import android.widget.TextView; - -import com.android.calendar.CalendarColorPickerDialog; -import com.android.calendar.Utils; -import com.android.calendar.selectcalendars.CalendarColorCache.OnCalendarColorsLoadedListener; - -import java.util.HashMap; - -import ws.xsoh.etar.R; - -public class SelectCalendarsSyncAdapter extends BaseAdapter - implements ListAdapter, AdapterView.OnItemClickListener, OnCalendarColorsLoadedListener { - private static final String TAG = "SelCalsAdapter"; - private static final String COLOR_PICKER_DIALOG_TAG = "ColorPickerDialog"; - private static final int LAYOUT = R.layout.calendar_sync_item; - private static int COLOR_CHIP_SIZE = 30; - private final String mSyncedString; - private final String mNotSyncedString; - private RectShape r = new RectShape(); - private CalendarColorPickerDialog mColorPickerDialog; - private CalendarColorCache mCache; - private LayoutInflater mInflater; - private CalendarRow[] mData; - private HashMap mChanges = new HashMap(); - private int mRowCount = 0; - private int mIdColumn; - private int mNameColumn; - private int mColorColumn; - private int mSyncedColumn; - private int mAccountNameColumn; - private int mAccountTypeColumn; - private boolean mIsTablet; - private FragmentManager mFragmentManager; - private int mColorViewTouchAreaIncrease; - - public SelectCalendarsSyncAdapter(Context context, Cursor c, FragmentManager manager) { - super(); - initData(c); - mCache = new CalendarColorCache(context, this); - mFragmentManager = manager; - mColorPickerDialog = (CalendarColorPickerDialog) - manager.findFragmentByTag(COLOR_PICKER_DIALOG_TAG); - mColorViewTouchAreaIncrease = context.getResources() - .getDimensionPixelSize(R.dimen.color_view_touch_area_increase); - mIsTablet = Utils.getConfigBool(context, R.bool.tablet_config); - mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); - COLOR_CHIP_SIZE *= context.getResources().getDisplayMetrics().density; - r.resize(COLOR_CHIP_SIZE, COLOR_CHIP_SIZE); - Resources res = context.getResources(); - mSyncedString = res.getString(R.string.synced); - mNotSyncedString = res.getString(R.string.not_synced); - } - - private static void setText(View view, int id, String text) { - if (TextUtils.isEmpty(text)) { - return; - } - TextView textView = (TextView) view.findViewById(id); - textView.setText(text); - } - - private void initData(Cursor c) { - if (c == null) { - mRowCount = 0; - mData = null; - return; - } - - mIdColumn = c.getColumnIndexOrThrow(Calendars._ID); - mNameColumn = c.getColumnIndexOrThrow(Calendars.CALENDAR_DISPLAY_NAME); - mColorColumn = c.getColumnIndexOrThrow(Calendars.CALENDAR_COLOR); - mSyncedColumn = c.getColumnIndexOrThrow(Calendars.SYNC_EVENTS); - mAccountNameColumn = c.getColumnIndexOrThrow(Calendars.ACCOUNT_NAME); - mAccountTypeColumn = c.getColumnIndexOrThrow(Calendars.ACCOUNT_TYPE); - - mRowCount = c.getCount(); - mData = new CalendarRow[mRowCount]; - c.moveToPosition(-1); - int p = 0; - while (c.moveToNext()) { - long id = c.getLong(mIdColumn); - mData[p] = new CalendarRow(); - mData[p].id = id; - mData[p].displayName = c.getString(mNameColumn); - mData[p].color = c.getInt(mColorColumn); - mData[p].originalSynced = c.getInt(mSyncedColumn) != 0; - mData[p].accountName = c.getString(mAccountNameColumn); - mData[p].accountType = c.getString(mAccountTypeColumn); - if (mChanges.containsKey(id)) { - mData[p].synced = mChanges.get(id).synced; - } else { - mData[p].synced = mData[p].originalSynced; - } - p++; - } - } - - public void changeCursor(Cursor c) { - initData(c); - notifyDataSetChanged(); - } - - @Override - public View getView(final int position, View convertView, ViewGroup parent) { - if (position >= mRowCount) { - return null; - } - String name = mData[position].displayName; - boolean selected = mData[position].synced; - int color = Utils.getDisplayColorFromColor(mData[position].color); - View view; - if (convertView == null) { - view = mInflater.inflate(LAYOUT, parent, false); - final View delegate = view.findViewById(R.id.color); - final View delegateParent = (View) delegate.getParent(); - delegateParent.post(new Runnable() { - - @Override - public void run() { - final Rect r = new Rect(); - delegate.getHitRect(r); - r.top -= mColorViewTouchAreaIncrease; - r.bottom += mColorViewTouchAreaIncrease; - r.left -= mColorViewTouchAreaIncrease; - r.right += mColorViewTouchAreaIncrease; - delegateParent.setTouchDelegate(new TouchDelegate(r, delegate)); - } - }); - } else { - view = convertView; - } - - view.setTag(mData[position]); - - CheckBox cb = (CheckBox) view.findViewById(R.id.sync); - cb.setChecked(selected); - - if (selected) { - setText(view, R.id.status, mSyncedString); - } else { - setText(view, R.id.status, mNotSyncedString); - } - - View colorView = view.findViewById(R.id.color); - colorView.setEnabled(hasMoreColors(position)); - colorView.setBackgroundColor(color); - colorView.setOnClickListener(new OnClickListener() { - - @Override - public void onClick(View v) { - // Purely for sanity check--view should be disabled if account has no more colors - if (!hasMoreColors(position)) { - return; - } - - if (mColorPickerDialog == null) { - mColorPickerDialog = CalendarColorPickerDialog.newInstance(mData[position].id, - mIsTablet); - } else { - mColorPickerDialog.setCalendarId(mData[position].id); - } - mFragmentManager.executePendingTransactions(); - if (!mColorPickerDialog.isAdded()) { - mColorPickerDialog.show(mFragmentManager, COLOR_PICKER_DIALOG_TAG); - } - } - }); - - setText(view, R.id.calendar, name); - return view; - } - - private boolean hasMoreColors(int position) { - return mCache.hasColors(mData[position].accountName, mData[position].accountType); - } - - @Override - public int getCount() { - return mRowCount; - } - - @Override - public Object getItem(int position) { - if (position >= mRowCount) { - return null; - } - CalendarRow item = mData[position]; - return item; - } - - @Override - public long getItemId(int position) { - if (position >= mRowCount) { - return 0; - } - return mData[position].id; - } - - @Override - public boolean hasStableIds() { - return true; - } - - public int getSynced(int position) { - return mData[position].synced ? 1 : 0; - } - - @Override - public void onItemClick(AdapterView parent, View view, int position, long id) { - CalendarRow row = (CalendarRow) view.getTag(); - row.synced = !row.synced; - - String status; - if (row.synced) { - status = mSyncedString; - } else { - status = mNotSyncedString; - } - setText(view, R.id.status, status); - - CheckBox cb = (CheckBox) view.findViewById(R.id.sync); - cb.setChecked(row.synced); - - // There is some data loss in long -> int, but we should never see it in - // practice regarding calendar ids. - mChanges.put(row.id, row); - } - - public HashMap getChanges() { - return mChanges; - } - - @Override - public void onCalendarColorsLoaded() { - notifyDataSetChanged(); - } - - public class CalendarRow { - long id; - String displayName; - int color; - boolean synced; - boolean originalSynced; - String accountName; - String accountType; - } -} diff --git a/src/com/android/calendar/selectcalendars/SelectCalendarsSyncFragment.java b/src/com/android/calendar/selectcalendars/SelectCalendarsSyncFragment.java deleted file mode 100644 index 5c2106fb0..000000000 --- a/src/com/android/calendar/selectcalendars/SelectCalendarsSyncFragment.java +++ /dev/null @@ -1,217 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.calendar.selectcalendars; - -import android.accounts.Account; -import android.app.Activity; -import android.app.ListFragment; -import android.app.LoaderManager; -import android.content.ContentResolver; -import android.content.ContentUris; -import android.content.ContentValues; -import android.content.CursorLoader; -import android.content.Intent; -import android.content.Loader; -import android.content.res.Resources; -import android.database.ContentObserver; -import android.database.Cursor; -import android.net.Uri; -import android.os.Bundle; -import android.os.Handler; -import android.provider.CalendarContract; -import android.provider.CalendarContract.Calendars; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.Button; -import android.widget.ListAdapter; -import android.widget.TextView; - -import com.android.calendar.AsyncQueryService; -import com.android.calendar.Utils; -import com.android.calendar.selectcalendars.SelectCalendarsSyncAdapter.CalendarRow; - -import java.util.HashMap; - -import ws.xsoh.etar.R; - -public class SelectCalendarsSyncFragment extends ListFragment - implements View.OnClickListener, LoaderManager.LoaderCallbacks { - - private static final String TAG = "SelectCalendarSync"; - - private static final String COLLATE_NOCASE = " COLLATE NOCASE"; - private static final String SELECTION = Calendars.ACCOUNT_NAME + "=? AND " - + Calendars.ACCOUNT_TYPE + "=?"; - // is primary lets us sort the user's main calendar to the top of the list - private static final String IS_PRIMARY = "\"primary\""; - private static final String SORT_ORDER = IS_PRIMARY + " DESC," + Calendars.CALENDAR_DISPLAY_NAME - + COLLATE_NOCASE; - - private static final String[] PROJECTION = new String[] { - Calendars._ID, - Calendars.CALENDAR_DISPLAY_NAME, - Calendars.CALENDAR_COLOR, - Calendars.SYNC_EVENTS, - Calendars.ACCOUNT_NAME, - Calendars.ACCOUNT_TYPE, - "(" + Calendars.ACCOUNT_NAME + "=" + Calendars.OWNER_ACCOUNT + ") AS " + IS_PRIMARY, }; - private final String[] mArgs = new String[2]; - private TextView mSyncStatus; - private Button mAccountsButton; - private Account mAccount; - private AsyncQueryService mService; - private Handler mHandler = new Handler(); - private ContentObserver mCalendarsObserver = new ContentObserver(mHandler) { - @Override - public void onChange(boolean selfChange) { - // We don't need our own sync changes to trigger refreshes. - if (!selfChange) { - getLoaderManager().initLoader(0, null, SelectCalendarsSyncFragment.this); - } - } - }; - - public SelectCalendarsSyncFragment() { - } - - public SelectCalendarsSyncFragment(Bundle bundle) { - mAccount = new Account(bundle.getString(Calendars.ACCOUNT_NAME), - bundle.getString(Calendars.ACCOUNT_TYPE)); - } - - @Override - public View onCreateView( - LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - View v = inflater.inflate(R.layout.account_calendars, null); - mSyncStatus = (TextView) v.findViewById(R.id.account_status); - mSyncStatus.setVisibility(View.GONE); - - mAccountsButton = (Button) v.findViewById(R.id.sync_settings); - mAccountsButton.setVisibility(View.GONE); - mAccountsButton.setOnClickListener(this); - - return v; - } - - @Override - public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - // Give some text to display if there is no data. In a real - // application this would come from a resource. - setEmptyText(getActivity().getText(R.string.no_syncable_calendars)); - // Prepare the loader. Either re-connect with an existing one, - // or start a new one. - getLoaderManager().initLoader(0, null, this); - } - - @Override - public void onResume() { - super.onResume(); - if (!ContentResolver.getMasterSyncAutomatically() - || !ContentResolver.getSyncAutomatically(mAccount, CalendarContract.AUTHORITY)) { - Resources res = getActivity().getResources(); - mSyncStatus.setText(res.getString(R.string.acct_not_synced)); - mSyncStatus.setVisibility(View.VISIBLE); - mAccountsButton.setText(res.getString(R.string.accounts)); - mAccountsButton.setVisibility(View.VISIBLE); - } else { - mSyncStatus.setVisibility(View.GONE); - mAccountsButton.setVisibility(View.GONE); - - // Start a background sync to get the list of calendars from the server. - Utils.startCalendarMetafeedSync(mAccount); - getActivity().getContentResolver().registerContentObserver( - Calendars.CONTENT_URI, true, mCalendarsObserver); - } - } - - @Override - public void onAttach(Activity activity) { - super.onAttach(activity); - mService = new AsyncQueryService(activity); - - Bundle bundle = getArguments(); - if (bundle != null && bundle.containsKey(Calendars.ACCOUNT_NAME) - && bundle.containsKey(Calendars.ACCOUNT_TYPE)) { - mAccount = new Account(bundle.getString(Calendars.ACCOUNT_NAME), - bundle.getString(Calendars.ACCOUNT_TYPE)); - } - } - - @Override - public void onPause() { - final ListAdapter listAdapter = getListAdapter(); - if (listAdapter != null) { - HashMap changes = ((SelectCalendarsSyncAdapter) listAdapter) - .getChanges(); - if (changes != null && changes.size() > 0) { - for (CalendarRow row : changes.values()) { - if (row.synced == row.originalSynced) { - continue; - } - long id = row.id; - mService.cancelOperation((int) id); - // Use the full long id in case it makes a difference - Uri uri = ContentUris.withAppendedId(Calendars.CONTENT_URI, row.id); - ContentValues values = new ContentValues(); - // Toggle the current setting - int synced = row.synced ? 1 : 0; - values.put(Calendars.SYNC_EVENTS, synced); - values.put(Calendars.VISIBLE, synced); - mService.startUpdate((int) id, null, uri, values, null, null, 0); - } - changes.clear(); - } - } - getActivity().getContentResolver().unregisterContentObserver(mCalendarsObserver); - super.onPause(); - } - - @Override - public Loader onCreateLoader(int id, Bundle args) { - mArgs[0] = mAccount.name; - mArgs[1] = mAccount.type; - return new CursorLoader( - getActivity(), Calendars.CONTENT_URI, PROJECTION, SELECTION, mArgs, SORT_ORDER); - } - - @Override - public void onLoadFinished(Loader loader, Cursor data) { - SelectCalendarsSyncAdapter adapter = (SelectCalendarsSyncAdapter) getListAdapter(); - if (adapter == null) { - adapter = new SelectCalendarsSyncAdapter(getActivity(), data, getFragmentManager()); - setListAdapter(adapter); - } else { - adapter.changeCursor(data); - } - getListView().setOnItemClickListener(adapter); - } - - public void onLoaderReset(Loader loader) { - setListAdapter(null); - } - - // Called when the Accounts button is pressed. Takes the user to the - // Accounts and Sync settings page. - @Override - public void onClick(View v) { - Intent intent = new Intent(); - intent.setAction("android.settings.SYNC_SETTINGS"); - getActivity().startActivity(intent); - } -} diff --git a/src/com/android/calendar/selectcalendars/SelectSyncedCalendarsMultiAccountActivity.java b/src/com/android/calendar/selectcalendars/SelectSyncedCalendarsMultiAccountActivity.java deleted file mode 100644 index 64e0361ae..000000000 --- a/src/com/android/calendar/selectcalendars/SelectSyncedCalendarsMultiAccountActivity.java +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.calendar.selectcalendars; - -import android.app.ActionBar; -import android.app.ExpandableListActivity; -import android.content.AsyncQueryHandler; -import android.content.Context; -import android.database.Cursor; -import android.database.MatrixCursor; -import android.os.Build; -import android.os.Bundle; -import android.provider.CalendarContract.Calendars; -import androidx.appcompat.widget.AppCompatCheckBox; -import androidx.appcompat.widget.AppCompatCheckedTextView; -import androidx.appcompat.widget.AppCompatEditText; -import androidx.appcompat.widget.AppCompatRadioButton; -import androidx.appcompat.widget.AppCompatSpinner; -import android.util.AttributeSet; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.widget.ExpandableListView; - -import com.android.calendar.DynamicTheme; -import com.android.calendar.Utils; - -import ws.xsoh.etar.R; - -public class SelectSyncedCalendarsMultiAccountActivity extends ExpandableListActivity - implements View.OnClickListener { - - private static final String TAG = "Calendar"; - private static final String EXPANDED_KEY = "is_expanded"; - private static final String ACCOUNT_UNIQUE_KEY = "ACCOUNT_KEY"; - private static final String[] PROJECTION = new String[] { - Calendars._ID, - Calendars.ACCOUNT_TYPE, - Calendars.ACCOUNT_NAME, - Calendars.ACCOUNT_TYPE + " || " + Calendars.ACCOUNT_NAME + " AS " + - ACCOUNT_UNIQUE_KEY, - }; - private MatrixCursor mAccountsCursor = null; - private ExpandableListView mList; - private SelectSyncedCalendarsMultiAccountAdapter mAdapter; - private final DynamicTheme dynamicTheme = new DynamicTheme(); - - @Override - protected void onCreate(Bundle icicle) { - super.onCreate(icicle); - dynamicTheme.onCreate(this); - setContentView(R.layout.select_calendars_multi_accounts_fragment); - mList = getExpandableListView(); - mList.setEmptyView(findViewById(R.id.loading)); - // Start a background sync to get the list of calendars from the server. - Utils.startCalendarMetafeedSync(null); - - findViewById(R.id.btn_done).setOnClickListener(this); - findViewById(R.id.btn_discard).setOnClickListener(this); - } - - @Override - public View onCreateView(String name, Context context, AttributeSet attrs) { - // Allow super to try and create a view first - final View result = super.onCreateView(name, context, attrs); - - if (result != null) { - return result; - } - - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { - // If we're running pre-L, we need to 'inject' our tint aware Views in place of the - // standard framework versions - switch (name) { - case "EditText": - return new AppCompatEditText(this, attrs); - case "Spinner": - return new AppCompatSpinner(this, attrs); - case "CheckBox": - return new AppCompatCheckBox(this, attrs); - case "RadioButton": - return new AppCompatRadioButton(this, attrs); - case "CheckedTextView": - return new AppCompatCheckedTextView(this, attrs); - } - } - return null; - } - - @Override - public void onClick(View view) { - if (view.getId() == R.id.btn_done) { - if (mAdapter != null) { - mAdapter.doSaveAction(); - } - finish(); - } else if (view.getId() == R.id.btn_discard) { - finish(); - } - } - - @Override - protected void onResume() { - super.onResume(); - dynamicTheme.onResume(this); - if (mAdapter != null) { - mAdapter.startRefreshStopDelay(); - } - new AsyncQueryHandler(getContentResolver()) { - @Override - protected void onQueryComplete(int token, Object cookie, Cursor cursor) { - mAccountsCursor = Utils.matrixCursorFromCursor(cursor); - - mAdapter = new SelectSyncedCalendarsMultiAccountAdapter( - findViewById(R.id.calendars).getContext(), mAccountsCursor, - SelectSyncedCalendarsMultiAccountActivity.this); - mList.setAdapter(mAdapter); - - // TODO initialize from sharepref - int count = mList.getCount(); - for(int i = 0; i < count; i++) { - mList.expandGroup(i); - } - } - }.startQuery(0, null, Calendars.CONTENT_URI, PROJECTION, - "1) GROUP BY (" + ACCOUNT_UNIQUE_KEY, //Cheap hack to make WHERE a GROUP BY query - null /* selectionArgs */, - Calendars.ACCOUNT_NAME /*sort order*/); - //TODO change to something that supports group by queries. - } - - @Override - protected void onPause() { - super.onPause(); - if (mAdapter != null) { - mAdapter.cancelRefreshStopDelay(); - } - } - - @Override - protected void onStop() { - super.onStop(); - if (mAdapter != null) { - mAdapter.closeChildrenCursors(); - } - if (mAccountsCursor != null && !mAccountsCursor.isClosed()) { - mAccountsCursor.close(); - } - } - - @Override - protected void onSaveInstanceState(Bundle outState) { - super.onSaveInstanceState(outState); - boolean[] isExpanded; - mList = getExpandableListView(); - if(mList != null) { - int count = mList.getCount(); - isExpanded = new boolean[count]; - for(int i = 0; i < count; i++) { - isExpanded[i] = mList.isGroupExpanded(i); - } - } else { - isExpanded = null; - } - outState.putBooleanArray(EXPANDED_KEY, isExpanded); - //TODO Store this to preferences instead so it remains on restart - } - - @Override - protected void onRestoreInstanceState(Bundle state) { - super.onRestoreInstanceState(state); - mList = getExpandableListView(); - boolean[] isExpanded = state.getBooleanArray(EXPANDED_KEY); - if(mList != null && isExpanded != null && mList.getCount() >= isExpanded.length) { - for(int i = 0; i < isExpanded.length; i++) { - if(isExpanded[i] && !mList.isGroupExpanded(i)) { - mList.expandGroup(i); - } else if(!isExpanded[i] && mList.isGroupExpanded(i)){ - mList.collapseGroup(i); - } - } - } - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - if (getActionBar() != null){ - getActionBar().setDisplayOptions(ActionBar.DISPLAY_HOME_AS_UP, ActionBar.DISPLAY_HOME_AS_UP); - } - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case android.R.id.home: - Utils.returnToCalendarHome(this); - return true; - } - return super.onOptionsItemSelected(item); - } -} diff --git a/src/com/android/calendar/selectcalendars/SelectSyncedCalendarsMultiAccountAdapter.java b/src/com/android/calendar/selectcalendars/SelectSyncedCalendarsMultiAccountAdapter.java deleted file mode 100644 index 5640dd6ae..000000000 --- a/src/com/android/calendar/selectcalendars/SelectSyncedCalendarsMultiAccountAdapter.java +++ /dev/null @@ -1,460 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.calendar.selectcalendars; - -import android.accounts.AccountManager; -import android.accounts.AuthenticatorDescription; -import android.app.FragmentManager; -import android.content.AsyncQueryHandler; -import android.content.ContentResolver; -import android.content.ContentUris; -import android.content.ContentValues; -import android.content.Context; -import android.content.pm.PackageManager; -import android.database.Cursor; -import android.database.MatrixCursor; -import android.graphics.Rect; -import android.net.Uri; -import android.provider.CalendarContract.Calendars; -import android.text.TextUtils; -import android.util.Log; -import android.view.LayoutInflater; -import android.view.TouchDelegate; -import android.view.View; -import android.view.View.OnClickListener; -import android.view.ViewGroup; -import android.widget.CheckBox; -import android.widget.CursorTreeAdapter; -import android.widget.TextView; - -import com.android.calendar.CalendarColorPickerDialog; -import com.android.calendar.Utils; -import com.android.calendar.selectcalendars.CalendarColorCache.OnCalendarColorsLoadedListener; - -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; - -import ws.xsoh.etar.R; - -public class SelectSyncedCalendarsMultiAccountAdapter extends CursorTreeAdapter implements - View.OnClickListener, OnCalendarColorsLoadedListener { - - private static final String TAG = "Calendar"; - private static final String COLOR_PICKER_DIALOG_TAG = "ColorPickerDialog"; - - private static final String IS_PRIMARY = "\"primary\""; - private static final String CALENDARS_ORDERBY = IS_PRIMARY + " DESC," - + Calendars.CALENDAR_DISPLAY_NAME + " COLLATE NOCASE"; - private static final String ACCOUNT_SELECTION = Calendars.ACCOUNT_NAME + "=?" - + " AND " + Calendars.ACCOUNT_TYPE + "=?"; - // This is to keep our update tokens separate from other tokens. Since we cancel old updates - // when a new update comes in, we'd like to leave a token space that won't be canceled. - private static final int MIN_UPDATE_TOKEN = 1000; - // How long to wait between requeries of the calendars to see if anything has changed. - private static final int REFRESH_DELAY = 5000; - // How long to keep refreshing for - private static final int REFRESH_DURATION = 60000; - private static final String[] PROJECTION = new String[] { - Calendars._ID, - Calendars.ACCOUNT_NAME, - Calendars.OWNER_ACCOUNT, - Calendars.CALENDAR_DISPLAY_NAME, - Calendars.CALENDAR_COLOR, - Calendars.VISIBLE, - Calendars.SYNC_EVENTS, - "(" + Calendars.ACCOUNT_NAME + "=" + Calendars.OWNER_ACCOUNT + ") AS " + IS_PRIMARY, - Calendars.ACCOUNT_TYPE - }; - //Keep these in sync with the projection - private static final int ID_COLUMN = 0; - private static final int ACCOUNT_COLUMN = 1; - private static final int OWNER_COLUMN = 2; - private static final int NAME_COLUMN = 3; - private static final int COLOR_COLUMN = 4; - private static final int SELECTED_COLUMN = 5; - private static final int SYNCED_COLUMN = 6; - private static final int PRIMARY_COLUMN = 7; - private static final int ACCOUNT_TYPE_COLUMN = 8; - private static final int TAG_ID_CALENDAR_ID = R.id.calendar; - private static final int TAG_ID_SYNC_CHECKBOX = R.id.sync; - private static int mUpdateToken = MIN_UPDATE_TOKEN; - private static boolean mRefresh = true; - private final static Runnable mStopRefreshing = new Runnable() { - @Override - public void run() { - mRefresh = false; - } - }; - private static String mSyncedText; - private static String mNotSyncedText; - // This is to keep track of whether or not multiple calendars have the same display name - private static HashMap mIsDuplicateName = new HashMap(); - private final LayoutInflater mInflater; - private final ContentResolver mResolver; - private final SelectSyncedCalendarsMultiAccountActivity mActivity; - private final FragmentManager mFragmentManager; - private final boolean mIsTablet; - private final View mView; - protected AuthenticatorDescription[] mAuthDescs; - private CalendarColorPickerDialog mColorPickerDialog; - private Map mTypeToAuthDescription - = new HashMap(); - // These track changes to the synced state of calendars - private Map mCalendarChanges - = new HashMap(); - private Map mCalendarInitialStates - = new HashMap(); - // Flag for when the cursors have all been closed to ensure no race condition with queries. - private boolean mClosedCursorsFlag; - // This is for keeping MatrixCursor copies so that we can requery in the background. - private Map mChildrenCursors - = new HashMap(); - private AsyncCalendarsUpdater mCalendarsUpdater; - private int mColorViewTouchAreaIncrease; - private CalendarColorCache mCache; - - public SelectSyncedCalendarsMultiAccountAdapter(Context context, Cursor acctsCursor, - SelectSyncedCalendarsMultiAccountActivity act) { - super(acctsCursor, context); - mSyncedText = context.getString(R.string.synced); - mNotSyncedText = context.getString(R.string.not_synced); - - mCache = new CalendarColorCache(context, this); - - mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); - mResolver = context.getContentResolver(); - mActivity = act; - mFragmentManager = act.getFragmentManager(); - mColorPickerDialog = (CalendarColorPickerDialog) - mFragmentManager.findFragmentByTag(COLOR_PICKER_DIALOG_TAG); - mIsTablet = Utils.getConfigBool(context, R.bool.tablet_config); - - if (mCalendarsUpdater == null) { - mCalendarsUpdater = new AsyncCalendarsUpdater(mResolver); - } - - if (acctsCursor == null || acctsCursor.getCount() == 0) { - Log.i(TAG, "SelectCalendarsAdapter: No accounts were returned!"); - } - // Collect proper description for account types - mAuthDescs = AccountManager.get(context).getAuthenticatorTypes(); - for (int i = 0; i < mAuthDescs.length; i++) { - mTypeToAuthDescription.put(mAuthDescs[i].type, mAuthDescs[i]); - } - mView = mActivity.getExpandableListView(); - mRefresh = true; - mClosedCursorsFlag = false; - - mColorViewTouchAreaIncrease = context.getResources() - .getDimensionPixelSize(R.dimen.color_view_touch_area_increase); - } - - private static void setText(View view, int id, String text) { - if (TextUtils.isEmpty(text)) { - return; - } - TextView textView = (TextView) view.findViewById(id); - textView.setText(text); - } - - /** - * Method for changing the sync state when a calendar's button is pressed. - * - * This gets called when the CheckBox for a calendar is clicked. It toggles - * the sync state for the associated calendar and saves a change of state to - * a hashmap. It also compares against the original value and removes any - * changes from the hashmap if this is back at its initial state. - */ - @Override - public void onClick(View v) { - long id = (Long) v.getTag(TAG_ID_CALENDAR_ID); - boolean newState; - boolean initialState = mCalendarInitialStates.get(id); - if (mCalendarChanges.containsKey(id)) { - // Negate to reflect the click - newState = !mCalendarChanges.get(id); - } else { - // Negate to reflect the click - newState = !initialState; - } - - if (newState == initialState) { - mCalendarChanges.remove(id); - } else { - mCalendarChanges.put(id, newState); - } - - ((CheckBox) v.getTag(TAG_ID_SYNC_CHECKBOX)).setChecked(newState); - setText(v, R.id.status, newState ? mSyncedText : mNotSyncedText); - } - - public void startRefreshStopDelay() { - mRefresh = true; - mView.postDelayed(mStopRefreshing, REFRESH_DURATION); - } - - public void cancelRefreshStopDelay() { - mView.removeCallbacks(mStopRefreshing); - } - - /* - * Write back the changes that have been made. The sync code will pick up any changes and - * do updates on its own. - */ - public void doSaveAction() { - // Cancel the previous operation - mCalendarsUpdater.cancelOperation(mUpdateToken); - mUpdateToken++; - // This is to allow us to do queries and updates with the same AsyncQueryHandler without - // accidently canceling queries. - if(mUpdateToken < MIN_UPDATE_TOKEN) { - mUpdateToken = MIN_UPDATE_TOKEN; - } - - Iterator changeKeys = mCalendarChanges.keySet().iterator(); - while (changeKeys.hasNext()) { - long id = changeKeys.next(); - boolean newSynced = mCalendarChanges.get(id); - - Uri uri = ContentUris.withAppendedId(Calendars.CONTENT_URI, id); - ContentValues values = new ContentValues(); - values.put(Calendars.VISIBLE, newSynced ? 1 : 0); - values.put(Calendars.SYNC_EVENTS, newSynced ? 1 : 0); - mCalendarsUpdater.startUpdate(mUpdateToken, id, uri, values, null, null); - } - } - - /** - * Gets the label associated with a particular account type. If none found, return null. - * @param accountType the type of account - * @return a CharSequence for the label or null if one cannot be found. - */ - protected CharSequence getLabelForType(final String accountType) { - CharSequence label = null; - if (mTypeToAuthDescription.containsKey(accountType)) { - try { - AuthenticatorDescription desc = mTypeToAuthDescription.get(accountType); - Context authContext = mActivity.createPackageContext(desc.packageName, 0); - label = authContext.getResources().getText(desc.labelId); - } catch (PackageManager.NameNotFoundException e) { - Log.w(TAG, "No label for account type " + ", type " + accountType); - } - } - return label; - } - - @Override - protected void bindChildView(View view, Context context, Cursor cursor, boolean isLastChild) { - final long id = cursor.getLong(ID_COLUMN); - String name = cursor.getString(NAME_COLUMN); - String owner = cursor.getString(OWNER_COLUMN); - final String accountName = cursor.getString(ACCOUNT_COLUMN); - final String accountType = cursor.getString(ACCOUNT_TYPE_COLUMN); - int color = Utils.getDisplayColorFromColor(cursor.getInt(COLOR_COLUMN)); - - final View colorSquare = view.findViewById(R.id.color); - colorSquare.setEnabled(mCache.hasColors(accountName, accountType)); - colorSquare.setBackgroundColor(color); - final View delegateParent = (View) colorSquare.getParent(); - delegateParent.post(new Runnable() { - - @Override - public void run() { - final Rect r = new Rect(); - colorSquare.getHitRect(r); - r.top -= mColorViewTouchAreaIncrease; - r.bottom += mColorViewTouchAreaIncrease; - r.left -= mColorViewTouchAreaIncrease; - r.right += mColorViewTouchAreaIncrease; - delegateParent.setTouchDelegate(new TouchDelegate(r, colorSquare)); - } - }); - colorSquare.setOnClickListener(new OnClickListener() { - - @Override - public void onClick(View v) { - if (!mCache.hasColors(accountName, accountType)) { - return; - } - if (mColorPickerDialog == null) { - mColorPickerDialog = CalendarColorPickerDialog.newInstance(id, mIsTablet); - } else { - mColorPickerDialog.setCalendarId(id); - } - mFragmentManager.executePendingTransactions(); - if (!mColorPickerDialog.isAdded()) { - mColorPickerDialog.show(mFragmentManager, COLOR_PICKER_DIALOG_TAG); - } - } - }); - if (mIsDuplicateName.containsKey(name) && mIsDuplicateName.get(name) && - !name.equalsIgnoreCase(owner)) { - name = new StringBuilder(name) - .append(Utils.OPEN_EMAIL_MARKER) - .append(owner) - .append(Utils.CLOSE_EMAIL_MARKER) - .toString(); - } - setText(view, R.id.calendar, name); - - // First see if the user has already changed the state of this calendar - Boolean sync = mCalendarChanges.get(id); - if (sync == null) { - sync = cursor.getInt(SYNCED_COLUMN) == 1; - mCalendarInitialStates.put(id, sync); - } - - CheckBox button = (CheckBox) view.findViewById(R.id.sync); - button.setChecked(sync); - setText(view, R.id.status, sync ? mSyncedText : mNotSyncedText); - - view.setTag(TAG_ID_CALENDAR_ID, id); - view.setTag(TAG_ID_SYNC_CHECKBOX, button); - view.setOnClickListener(this); - } - - @Override - protected void bindGroupView(View view, Context context, Cursor cursor, boolean isExpanded) { - int accountColumn = cursor.getColumnIndexOrThrow(Calendars.ACCOUNT_NAME); - int accountTypeColumn = cursor.getColumnIndexOrThrow(Calendars.ACCOUNT_TYPE); - String account = cursor.getString(accountColumn); - String accountType = cursor.getString(accountTypeColumn); - CharSequence accountLabel = getLabelForType(accountType); - setText(view, R.id.account, account); - if (accountLabel != null) { - setText(view, R.id.account_type, accountLabel.toString()); - } - } - - @Override - protected Cursor getChildrenCursor(Cursor groupCursor) { - int accountColumn = groupCursor.getColumnIndexOrThrow(Calendars.ACCOUNT_NAME); - int accountTypeColumn = groupCursor.getColumnIndexOrThrow(Calendars.ACCOUNT_TYPE); - String account = groupCursor.getString(accountColumn); - String accountType = groupCursor.getString(accountTypeColumn); - //Get all the calendars for just this account. - Cursor childCursor = mChildrenCursors.get(accountType + "#" + account); - new RefreshCalendars(groupCursor.getPosition(), account, accountType).run(); - return childCursor; - } - - @Override - protected View newChildView(Context context, Cursor cursor, boolean isLastChild, - ViewGroup parent) { - return mInflater.inflate(R.layout.calendar_sync_item, parent, false); - } - - @Override - protected View newGroupView(Context context, Cursor cursor, boolean isExpanded, - ViewGroup parent) { - return mInflater.inflate(R.layout.account_item, parent, false); - } - - public void closeChildrenCursors() { - synchronized (mChildrenCursors) { - for (String key : mChildrenCursors.keySet()) { - Cursor cursor = mChildrenCursors.get(key); - if (!cursor.isClosed()) { - cursor.close(); - } - } - mChildrenCursors.clear(); - mClosedCursorsFlag = true; - } - } - - @Override - public void onCalendarColorsLoaded() { - notifyDataSetChanged(); - } - - private class AsyncCalendarsUpdater extends AsyncQueryHandler { - - public AsyncCalendarsUpdater(ContentResolver cr) { - super(cr); - } - - @Override - protected void onQueryComplete(int token, Object cookie, Cursor cursor) { - if (cursor == null) { - return; - } - synchronized (mChildrenCursors) { - if (mClosedCursorsFlag || (mActivity != null && mActivity.isFinishing())) { - cursor.close(); - return; - } - } - - Cursor currentCursor = mChildrenCursors.get(cookie); - // Check if the new cursor has the same content as our old cursor - if (currentCursor != null) { - if (Utils.compareCursors(currentCursor, cursor)) { - cursor.close(); - return; - } - } - // If not then make a new matrix cursor for our Map - MatrixCursor newCursor = Utils.matrixCursorFromCursor(cursor); - cursor.close(); - // And update our list of duplicated names - Utils.checkForDuplicateNames(mIsDuplicateName, newCursor, NAME_COLUMN); - - mChildrenCursors.put((String) cookie, newCursor); - try { - setChildrenCursor(token, newCursor); - } catch (NullPointerException e) { - Log.w(TAG, "Adapter expired, try again on the next query: " + e); - } - // Clean up our old cursor if we had one. We have to do this after setting the new - // cursor so that our view doesn't throw on an invalid cursor. - if (currentCursor != null) { - currentCursor.close(); - } - } - } - - private class RefreshCalendars implements Runnable { - - int mToken; - String mAccount; - String mAccountType; - - public RefreshCalendars(int token, String account, String accountType) { - mToken = token; - mAccount = account; - mAccountType = accountType; - } - - @Override - public void run() { - mCalendarsUpdater.cancelOperation(mToken); - // Set up a refresh for some point in the future if we haven't stopped updates yet - if(mRefresh) { - mView.postDelayed(new RefreshCalendars(mToken, mAccount, mAccountType), - REFRESH_DELAY); - } - mCalendarsUpdater.startQuery(mToken, - mAccountType + "#" + mAccount, - Calendars.CONTENT_URI, PROJECTION, - ACCOUNT_SELECTION, - new String[] { mAccount, mAccountType } /*selectionArgs*/, - CALENDARS_ORDERBY); - } - } -} diff --git a/src/com/android/calendar/selectcalendars/SelectVisibleCalendarsActivity.java b/src/com/android/calendar/selectcalendars/SelectVisibleCalendarsActivity.java deleted file mode 100644 index ccbefb263..000000000 --- a/src/com/android/calendar/selectcalendars/SelectVisibleCalendarsActivity.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.calendar.selectcalendars; - -import android.Manifest; -import android.app.ActionBar; -import android.app.FragmentTransaction; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.database.ContentObserver; -import android.os.Build; -import android.os.Bundle; -import android.os.Handler; -import android.provider.CalendarContract; -import androidx.appcompat.widget.Toolbar; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; - -import com.android.calendar.AbstractCalendarActivity; -import com.android.calendar.CalendarController; -import com.android.calendar.CalendarController.EventType; -import com.android.calendar.CalendarController.ViewType; -import com.android.calendar.DynamicTheme; -import com.android.calendar.Utils; - -import androidx.core.content.ContextCompat; - -import ws.xsoh.etar.R; - -public class SelectVisibleCalendarsActivity extends AbstractCalendarActivity { - private SelectVisibleCalendarsFragment mFragment; - private CalendarController mController; - - // Create an observer so that we can update the views whenever a - // Calendar event changes. - private final ContentObserver mObserver = new ContentObserver(new Handler()) { - @Override - public boolean deliverSelfNotifications() { - return true; - } - - @Override - public void onChange(boolean selfChange) { - mController.sendEvent(this, EventType.EVENTS_CHANGED, null, null, -1, ViewType.CURRENT); - } - }; - - private final DynamicTheme dynamicTheme = new DynamicTheme(); - - @Override - protected void onCreate(Bundle icicle) { - super.onCreate(icicle); - - dynamicTheme.onCreate(this); - setContentView(R.layout.simple_frame_layout_material); - Toolbar toolbar = findViewById(R.id.toolbar); - setSupportActionBar(toolbar); - mController = CalendarController.getInstance(this); - mFragment = (SelectVisibleCalendarsFragment) getFragmentManager().findFragmentById( - R.id.body_frame); - - if (mFragment == null) { - mFragment = new SelectVisibleCalendarsFragment(R.layout.calendar_sync_item); - - FragmentTransaction ft = getFragmentManager().beginTransaction(); - ft.replace(R.id.body_frame, mFragment); - ft.show(mFragment); - ft.commit(); - } - } - - @Override - public void onResume() { - super.onResume(); - if (Build.VERSION.SDK_INT < 23 || ContextCompat.checkSelfPermission(this, - Manifest.permission.READ_CALENDAR) == PackageManager.PERMISSION_GRANTED) { - getContentResolver().registerContentObserver(CalendarContract.Events.CONTENT_URI, - true, mObserver); - } - } - - @Override - public void onPause() { - super.onPause(); - getContentResolver().unregisterContentObserver(mObserver); - } - - // Needs to be in proguard whitelist - // Specified as listener via android:onClick in a layout xml - public void handleSelectSyncedCalendarsClicked(View v) { - Intent intent = new Intent(Intent.ACTION_VIEW); - intent.setClass(this, SelectSyncedCalendarsMultiAccountActivity.class); - intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_SINGLE_TOP); - startActivity(intent); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - if (getSupportActionBar() != null) { - getSupportActionBar().setDisplayOptions(ActionBar.DISPLAY_HOME_AS_UP, ActionBar.DISPLAY_HOME_AS_UP); - } - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case android.R.id.home: - Utils.returnToCalendarHome(this); - return true; - } - return super.onOptionsItemSelected(item); - } -} diff --git a/src/com/android/calendar/selectcalendars/SelectVisibleCalendarsFragment.java b/src/com/android/calendar/selectcalendars/SelectVisibleCalendarsFragment.java index f52d9183f..929157bcd 100644 --- a/src/com/android/calendar/selectcalendars/SelectVisibleCalendarsFragment.java +++ b/src/com/android/calendar/selectcalendars/SelectVisibleCalendarsFragment.java @@ -39,6 +39,9 @@ import com.android.calendar.selectcalendars.CalendarColorCache.OnCalendarColorsL import ws.xsoh.etar.R; +/** + * TODO: This fragment is still used in the tablet design + */ public class SelectVisibleCalendarsFragment extends Fragment implements AdapterView.OnItemClickListener, CalendarController.EventHandler, OnCalendarColorsLoadedListener { diff --git a/src/com/android/calendar/settings/GeneralPreferences.kt b/src/com/android/calendar/settings/GeneralPreferences.kt index 9daa373e5..644b40fbd 100644 --- a/src/com/android/calendar/settings/GeneralPreferences.kt +++ b/src/com/android/calendar/settings/GeneralPreferences.kt @@ -19,6 +19,7 @@ package com.android.calendar.settings import android.annotation.TargetApi import android.app.backup.BackupManager +import android.content.ComponentName import android.content.Context import android.content.Intent import android.content.SharedPreferences @@ -70,6 +71,10 @@ class GeneralPreferences : PreferenceFragmentCompat(), private lateinit var mSnoozeDelay: ListPreference private lateinit var mDefaultStart: ListPreference + // experimental + private lateinit var mCopyDb: Preference + private lateinit var mSkipReminders: ListPreference + private var mTimeZoneId: String? = null // Used to retrieve the color id from the color picker @@ -130,6 +135,8 @@ class GeneralPreferences : PreferenceFragmentCompat(), mDefaultEventDuration.summary = mDefaultEventDuration.entry mHomeTZ = preferenceScreen.findPreference(KEY_HOME_TZ) mSnoozeDelay = preferenceScreen.findPreference(KEY_DEFAULT_SNOOZE_DELAY)!! + mCopyDb = preferenceScreen.findPreference(KEY_OTHER_COPY_DB)!! + mSkipReminders = preferenceScreen.findPreference(KEY_OTHER_REMINDERS_RESPONDED)!! buildSnoozeDelayEntries() mTheme.summary = mTheme.entry mWeekStart.summary = mWeekStart.entry @@ -158,6 +165,36 @@ class GeneralPreferences : PreferenceFragmentCompat(), val tzpd = activity!!.supportFragmentManager .findFragmentByTag(FRAG_TAG_TIME_ZONE_PICKER) as TimeZonePickerDialogX? tzpd?.setOnTimeZoneSetListener(this) + + var skipPreferencesValue: String? = null + if (mSkipReminders != null) { + skipPreferencesValue = mSkipReminders.value + mSkipReminders.onPreferenceChangeListener = this + } + updateSkipRemindersSummary(skipPreferencesValue) + } + + /** + * Update the summary for the SkipReminders preference. + * @param value The corresponding value of which summary to set. If null, the default summary + * will be set, and the value will be set accordingly too. + */ + private fun updateSkipRemindersSummary(value: String?) { + if (mSkipReminders != null) { // Default to "declined". Must match with R.array.preferences_skip_reminders_values. + var index = 0 + val values = mSkipReminders.entryValues + val entries = mSkipReminders.entries + for (value_i in values.indices) { + if (values[value_i] == value) { + index = value_i + break + } + } + mSkipReminders.summary = entries[index].toString() + if (value == null) { // Value was not known ahead of time, so the default value will be set. + mSkipReminders.value = values[index].toString() + } + } } private fun showColorPickerDialog() { @@ -300,15 +337,18 @@ class GeneralPreferences : PreferenceFragmentCompat(), mSnoozeDelay.value = newValue as String mSnoozeDelay.summary = mSnoozeDelay.entry } - mVibrate -> { - mVibrate.isChecked = newValue as Boolean - return true - } mDefaultStart -> { val i = mDefaultStart.findIndexOfValue(newValue as String) mDefaultStart.summary = mDefaultStart.entries[i] return true } + mSkipReminders -> { + updateSkipRemindersSummary(newValue as String) + } + mVibrate -> { + mVibrate.isChecked = newValue as Boolean + return true + } else -> { return true } @@ -362,10 +402,21 @@ class GeneralPreferences : PreferenceFragmentCompat(), showNotificationChannel() return true } + KEY_OTHER_COPY_DB -> { + showDbCopy() + return true + } else -> return super.onPreferenceTreeClick(preference) } } + private fun showDbCopy() { + val intent = Intent(Intent.ACTION_MAIN) + intent.component = ComponentName("com.android.providers.calendar", + "com.android.providers.calendar.CalendarDebugActivity") + startActivity(intent) + } + private fun clearSearchHistory() { val suggestions = SearchRecentSuggestions(activity, Utils.getSearchAuthority(activity), @@ -498,6 +549,9 @@ class GeneralPreferences : PreferenceFragmentCompat(), private const val KEY_HOME_TZ = "preferences_home_tz" private const val FRAG_TAG_TIME_ZONE_PICKER = "TimeZonePicker" + // experimental + const val KEY_OTHER_COPY_DB = "preferences_copy_db" + const val KEY_OTHER_REMINDERS_RESPONDED = "preferences_reminders_responded" internal const val REQUEST_CODE_ALERT_RINGTONE = 42 @@ -505,5 +559,16 @@ class GeneralPreferences : PreferenceFragmentCompat(), fun getSharedPreferences(context: Context): SharedPreferences { return context.getSharedPreferences(SHARED_PREFS_NAME, Context.MODE_PRIVATE) } + + /** Set the default shared preferences in the proper context */ + fun setDefaultValues(context: Context) { + if (Utils.isOreoOrLater()) { + PreferenceManager.setDefaultValues(context, SHARED_PREFS_NAME, Context.MODE_PRIVATE, + R.xml.general_preferences_oreo_and_up, true); + } else { + PreferenceManager.setDefaultValues(context, SHARED_PREFS_NAME, Context.MODE_PRIVATE, + R.xml.general_preferences_below_oreo, true); + } + } } } diff --git a/src/com/android/calendar/settings/SettingsActivity.kt b/src/com/android/calendar/settings/SettingsActivity.kt index 3c0d21b1d..7b0e6b33e 100644 --- a/src/com/android/calendar/settings/SettingsActivity.kt +++ b/src/com/android/calendar/settings/SettingsActivity.kt @@ -28,6 +28,8 @@ import ws.xsoh.etar.R private const val TITLE_TAG = "settingsActivityTitle" +const val EXTRA_SHOW_FRAGMENT = "settingsShowFragment" + class SettingsActivity : AppCompatActivity(), PreferenceFragmentCompat.OnPreferenceStartFragmentCallback { @@ -37,6 +39,15 @@ class SettingsActivity : AppCompatActivity(), dynamicTheme.onCreate(this) super.onCreate(savedInstanceState) + val fragment = if (intent.hasExtra(EXTRA_SHOW_FRAGMENT)) { + supportFragmentManager.fragmentFactory.instantiate( + classLoader, + intent.getStringExtra(EXTRA_SHOW_FRAGMENT)!! + ) + } else { + MainListPreferences() + } + setContentView(R.layout.simple_frame_layout_material) val toolbar = findViewById(R.id.toolbar) setSupportActionBar(toolbar) @@ -44,7 +55,7 @@ class SettingsActivity : AppCompatActivity(), if (savedInstanceState == null) { supportFragmentManager .beginTransaction() - .replace(R.id.body_frame, MainListPreferences()) + .replace(R.id.body_frame, fragment) .commit() } else { title = savedInstanceState.getCharSequence(TITLE_TAG) diff --git a/src/com/android/calendar/settings/ViewDetailsPreferences.kt b/src/com/android/calendar/settings/ViewDetailsPreferences.kt index d3894f51b..3a450c9ba 100644 --- a/src/com/android/calendar/settings/ViewDetailsPreferences.kt +++ b/src/com/android/calendar/settings/ViewDetailsPreferences.kt @@ -101,9 +101,12 @@ class ViewDetailsPreferences : PreferenceFragmentCompat() { } class Preferences { - val TIME_VISIBILITY: TimeVisibility - val LOCATION_VISIBILITY: Boolean - val MAX_LINES: Int + @JvmField + var TIME_VISIBILITY: TimeVisibility + @JvmField + var LOCATION_VISIBILITY: Boolean + @JvmField + var MAX_LINES: Int constructor(context: Context) { val prefs = DynamicPreferences(context) -- GitLab From 33a5d645091ef08b8f354f09cf25c09c8298c4c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Thu, 9 Jan 2020 00:18:30 +0100 Subject: [PATCH 55/95] Improving preferences design and offline calendar --- AndroidManifest.xml | 18 +-- build.gradle | 3 + gradle/wrapper/gradle-wrapper.properties | 3 +- res/drawable/ic_menu_help.xml | 9 ++ .../ic_menu_select_visible_calendars.xml | 5 - res/drawable/ic_sync_off_dark.xml | 10 ++ .../{sync_off.xml => ic_sync_off_light.xml} | 0 res/layout/account_calendars.xml | 40 ------- res/layout/account_item.xml | 42 ------- res/layout/add_offline_calendar_dialog.xml | 4 +- res/layout/calendar_sync_item.xml | 73 ------------ ...lect_calendars_multi_accounts_fragment.xml | 74 ------------ res/layout/timezone_footer.xml | 27 ----- res/menu/calendar_view.xml | 5 + res/menu/settings_title_bar.xml | 23 ---- res/values/attrs.xml | 1 + res/values/colors.xml | 28 +++++ res/values/strings.xml | 103 +---------------- res/values/styles.xml | 1 + res/values/themes.xml | 2 + res/xml/calendar_settings_headers.xml | 24 ---- .../android/calendar/AllInOneActivity.java | 6 + .../android/calendar/CalendarBackupAgent.java | 2 +- src/com/android/calendar/Utils.java | 6 +- .../android/calendar/alerts/AlertService.java | 2 +- .../android/calendar/persistence/Calendar.kt | 6 +- .../persistence/CalendarRepository.kt | 91 +++++++++++---- .../SelectCalendarsSimpleAdapter.java | 54 ++------- .../AddOfflineCalendarDialogFragment.kt | 54 +++++++-- .../settings/CalendarColorPickerDialogX.kt | 52 ++------- .../calendar/settings/CalendarPreferences.kt | 25 +++-- .../calendar/settings/ColorFilterExtension.kt | 105 ++++++++++++++++++ .../calendar/settings/GeneralPreferences.kt | 96 ++++++++-------- .../calendar/settings/MainListPreferences.kt | 43 ++++--- .../settings/MainListViewModelFactory.kt | 1 + .../calendar/settings/SettingsActivity.kt | 6 + .../settings/TimeZonePickerDialogX.java | 13 ++- .../settings/ViewDetailsPreferences.kt | 14 +-- 38 files changed, 434 insertions(+), 637 deletions(-) create mode 100644 res/drawable/ic_menu_help.xml delete mode 100644 res/drawable/ic_menu_select_visible_calendars.xml create mode 100644 res/drawable/ic_sync_off_dark.xml rename res/drawable/{sync_off.xml => ic_sync_off_light.xml} (100%) delete mode 100644 res/layout/account_calendars.xml delete mode 100644 res/layout/account_item.xml delete mode 100644 res/layout/calendar_sync_item.xml delete mode 100644 res/layout/select_calendars_multi_accounts_fragment.xml delete mode 100644 res/layout/timezone_footer.xml delete mode 100644 res/menu/settings_title_bar.xml delete mode 100644 res/xml/calendar_settings_headers.xml create mode 100644 src/com/android/calendar/settings/ColorFilterExtension.kt diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 5929d6432..2ac6bd43f 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -19,15 +19,7 @@ --> - - - + android:installLocation="auto"> @@ -141,14 +133,6 @@ - - - - + + \ No newline at end of file diff --git a/res/drawable/ic_menu_select_visible_calendars.xml b/res/drawable/ic_menu_select_visible_calendars.xml deleted file mode 100644 index 6478d1bc2..000000000 --- a/res/drawable/ic_menu_select_visible_calendars.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/res/drawable/ic_sync_off_dark.xml b/res/drawable/ic_sync_off_dark.xml new file mode 100644 index 000000000..965a592a8 --- /dev/null +++ b/res/drawable/ic_sync_off_dark.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/res/drawable/sync_off.xml b/res/drawable/ic_sync_off_light.xml similarity index 100% rename from res/drawable/sync_off.xml rename to res/drawable/ic_sync_off_light.xml diff --git a/res/layout/account_calendars.xml b/res/layout/account_calendars.xml deleted file mode 100644 index ac0fbae8a..000000000 --- a/res/layout/account_calendars.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - -