diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/activities/EventActivity.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/activities/EventActivity.kt index 2e29600bb..cef25176b 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/activities/EventActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/activities/EventActivity.kt @@ -46,7 +46,6 @@ import kotlinx.android.synthetic.main.activity_event.view.event_reminder_3 import kotlinx.android.synthetic.main.item_attendee.view.* import org.joda.time.DateTime import org.joda.time.DateTimeZone -import java.util.Calendar import java.util.TimeZone import java.util.regex.Pattern @@ -795,7 +794,7 @@ class EventActivity : SimpleActivity() { private fun checkRepetitionRuleText() { when { mRepeatInterval.isXWeeklyRepetition() -> { - event_repetition_rule.text = if (mRepeatRule == EVERY_DAY_BIT) getString(R.string.every_day) else getSelectedDaysString(mRepeatRule) + event_repetition_rule.text = if (mRepeatRule == EVERY_DAY_BIT) getString(R.string.every_day) else getShortDaysFromBitmask(mRepeatRule) } mRepeatInterval.isXMonthlyRepetition() -> { @@ -1449,13 +1448,13 @@ class EventActivity : SimpleActivity() { private fun setupStartDate() { hideKeyboard() - val datepicker = DatePickerDialog( + val datePicker = DatePickerDialog( this, getDatePickerDialogTheme(), startDateSetListener, mEventStartDateTime.year, mEventStartDateTime.monthOfYear - 1, mEventStartDateTime.dayOfMonth ) - datepicker.datePicker.firstDayOfWeek = if (config.isSundayFirst) Calendar.SUNDAY else Calendar.MONDAY - datepicker.show() + datePicker.datePicker.firstDayOfWeek = getJavaDayOfWeekFromJoda(config.firstDayOfWeek) + datePicker.show() } private fun setupStartTime() { @@ -1493,13 +1492,13 @@ class EventActivity : SimpleActivity() { private fun setupEndDate() { hideKeyboard() - val datepicker = DatePickerDialog( + val datePicker = DatePickerDialog( this, getDatePickerDialogTheme(), endDateSetListener, mEventEndDateTime.year, mEventEndDateTime.monthOfYear - 1, mEventEndDateTime.dayOfMonth ) - datepicker.datePicker.firstDayOfWeek = if (config.isSundayFirst) Calendar.SUNDAY else Calendar.MONDAY - datepicker.show() + datePicker.datePicker.firstDayOfWeek = getJavaDayOfWeekFromJoda(config.firstDayOfWeek) + datePicker.show() } private fun setupEndTime() { diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/activities/MainActivity.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/activities/MainActivity.kt index 5127bd447..dfe3cb4e8 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/activities/MainActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/activities/MainActivity.kt @@ -73,7 +73,7 @@ class MainActivity : SimpleActivity(), RefreshRecyclerViewListener { private var mStoredBackgroundColor = 0 private var mStoredPrimaryColor = 0 private var mStoredDayCode = "" - private var mStoredIsSundayFirst = false + private var mStoredFirstDayOfWeek = 0 private var mStoredMidnightSpan = true private var mStoredUse24HourFormat = false private var mStoredDimPastEvents = true @@ -183,7 +183,7 @@ class MainActivity : SimpleActivity(), RefreshRecyclerViewListener { } if (config.storedView == WEEKLY_VIEW) { - if (mStoredIsSundayFirst != config.isSundayFirst || mStoredUse24HourFormat != config.use24HourFormat + if (mStoredFirstDayOfWeek != config.firstDayOfWeek || mStoredUse24HourFormat != config.use24HourFormat || mStoredMidnightSpan != config.showMidnightSpanningEventsAtTop || mStoredStartWeekWithCurrentDay != config.startWeekWithCurrentDay ) { updateViewPager() @@ -318,7 +318,7 @@ class MainActivity : SimpleActivity(), RefreshRecyclerViewListener { mStoredPrimaryColor = getProperPrimaryColor() mStoredBackgroundColor = getProperBackgroundColor() config.apply { - mStoredIsSundayFirst = isSundayFirst + mStoredFirstDayOfWeek = firstDayOfWeek mStoredUse24HourFormat = use24HourFormat mStoredDimPastEvents = dimPastEvents mStoredDimCompletedTasks = dimCompletedTasks diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/activities/SettingsActivity.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/activities/SettingsActivity.kt index 328797a64..76ea629a6 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/activities/SettingsActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/activities/SettingsActivity.kt @@ -26,6 +26,7 @@ import com.simplemobiletools.commons.models.AlarmSound import com.simplemobiletools.commons.models.RadioItem import kotlinx.android.synthetic.main.activity_settings.* import org.joda.time.DateTime +import org.joda.time.DateTimeConstants import java.io.File import java.io.InputStream import java.text.SimpleDateFormat @@ -63,7 +64,7 @@ class SettingsActivity : SimpleActivity() { setupManageQuickFilterEventTypes() setupHourFormat() setupAllowCreatingTasks() - setupSundayFirst() + setupStartWeekOn() setupHighlightWeekends() setupHighlightWeekendsColor() setupDeleteAllEvents() @@ -343,11 +344,24 @@ class SettingsActivity : SimpleActivity() { } } - private fun setupSundayFirst() { - settings_sunday_first.isChecked = config.isSundayFirst - settings_sunday_first_holder.setOnClickListener { - settings_sunday_first.toggle() - config.isSundayFirst = settings_sunday_first.isChecked + private fun setupStartWeekOn() { + val items = arrayListOf( + RadioItem(DateTimeConstants.SUNDAY, getString(R.string.sunday)), + RadioItem(DateTimeConstants.MONDAY, getString(R.string.monday)), + RadioItem(DateTimeConstants.TUESDAY, getString(R.string.tuesday)), + RadioItem(DateTimeConstants.WEDNESDAY, getString(R.string.wednesday)), + RadioItem(DateTimeConstants.THURSDAY, getString(R.string.thursday)), + RadioItem(DateTimeConstants.FRIDAY, getString(R.string.friday)), + RadioItem(DateTimeConstants.SATURDAY, getString(R.string.saturday)), + ) + + settings_start_week_on.text = getDayOfWeekString(config.firstDayOfWeek) + settings_start_week_on_holder.setOnClickListener { + RadioGroupDialog(this, items, config.firstDayOfWeek) { any -> + val firstDayOfWeek = any as Int + config.firstDayOfWeek = firstDayOfWeek + settings_start_week_on.text = getDayOfWeekString(firstDayOfWeek) + } } } @@ -919,7 +933,7 @@ class SettingsActivity : SimpleActivity() { put(USE_SAME_SNOOZE, config.useSameSnooze) put(SNOOZE_TIME, config.snoozeTime) put(USE_24_HOUR_FORMAT, config.use24HourFormat) - put(SUNDAY_FIRST, config.isSundayFirst) + put(FIRST_DAY_OF_WEEK, config.firstDayOfWeek) put(HIGHLIGHT_WEEKENDS, config.highlightWeekends) put(HIGHLIGHT_WEEKENDS_COLOR, config.highlightWeekendsColor) put(ALLOW_CREATING_TASKS, config.allowCreatingTasks) @@ -1028,7 +1042,8 @@ class SettingsActivity : SimpleActivity() { USE_SAME_SNOOZE -> config.useSameSnooze = value.toBoolean() SNOOZE_TIME -> config.snoozeTime = value.toInt() USE_24_HOUR_FORMAT -> config.use24HourFormat = value.toBoolean() - SUNDAY_FIRST -> config.isSundayFirst = value.toBoolean() + SUNDAY_FIRST -> config.firstDayOfWeek = DateTimeConstants.SUNDAY + FIRST_DAY_OF_WEEK -> config.firstDayOfWeek = value.toInt() HIGHLIGHT_WEEKENDS -> config.highlightWeekends = value.toBoolean() HIGHLIGHT_WEEKENDS_COLOR -> config.highlightWeekendsColor = value.toInt() ALLOW_CREATING_TASKS -> config.allowCreatingTasks = value.toBoolean() diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/activities/TaskActivity.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/activities/TaskActivity.kt index 84df33745..1981bd7d5 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/activities/TaskActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/activities/TaskActivity.kt @@ -25,7 +25,6 @@ import com.simplemobiletools.commons.helpers.* import com.simplemobiletools.commons.models.RadioItem import kotlinx.android.synthetic.main.activity_task.* import org.joda.time.DateTime -import java.util.Calendar import kotlin.math.pow class TaskActivity : SimpleActivity() { @@ -536,7 +535,7 @@ class TaskActivity : SimpleActivity() { this, getDatePickerDialogTheme(), dateSetListener, mTaskDateTime.year, mTaskDateTime.monthOfYear - 1, mTaskDateTime.dayOfMonth ) - datePicker.datePicker.firstDayOfWeek = if (config.isSundayFirst) Calendar.SUNDAY else Calendar.MONDAY + datePicker.datePicker.firstDayOfWeek = getJavaDayOfWeekFromJoda(config.firstDayOfWeek) datePicker.show() } @@ -985,7 +984,7 @@ class TaskActivity : SimpleActivity() { private fun checkRepetitionRuleText() { when { mRepeatInterval.isXWeeklyRepetition() -> { - task_repetition_rule.text = if (mRepeatRule == EVERY_DAY_BIT) getString(R.string.every_day) else getSelectedDaysString(mRepeatRule) + task_repetition_rule.text = if (mRepeatRule == EVERY_DAY_BIT) getString(R.string.every_day) else getShortDaysFromBitmask(mRepeatRule) } mRepeatInterval.isXMonthlyRepetition() -> { val repeatString = if (mRepeatRule == REPEAT_ORDER_WEEKDAY_USE_LAST || mRepeatRule == REPEAT_ORDER_WEEKDAY) diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/activities/WidgetMonthlyConfigureActivity.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/activities/WidgetMonthlyConfigureActivity.kt index 8f43408a9..06deea9e0 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/activities/WidgetMonthlyConfigureActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/activities/WidgetMonthlyConfigureActivity.kt @@ -16,18 +16,21 @@ import android.widget.TextView import com.simplemobiletools.calendar.pro.R import com.simplemobiletools.calendar.pro.extensions.addDayEvents import com.simplemobiletools.calendar.pro.extensions.config +import com.simplemobiletools.calendar.pro.extensions.isWeekendIndex import com.simplemobiletools.calendar.pro.helpers.MonthlyCalendarImpl import com.simplemobiletools.calendar.pro.helpers.MyWidgetMonthlyProvider -import com.simplemobiletools.calendar.pro.helpers.isWeekend import com.simplemobiletools.calendar.pro.interfaces.MonthlyCalendar import com.simplemobiletools.calendar.pro.models.DayMonthly import com.simplemobiletools.commons.dialogs.ColorPickerDialog import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.helpers.IS_CUSTOMIZING_COLORS import com.simplemobiletools.commons.helpers.LOWER_ALPHA -import kotlinx.android.synthetic.main.day_monthly_number_view.view.* -import kotlinx.android.synthetic.main.first_row.* -import kotlinx.android.synthetic.main.top_navigation.* +import kotlinx.android.synthetic.main.day_monthly_number_view.view.day_monthly_number_background +import kotlinx.android.synthetic.main.day_monthly_number_view.view.day_monthly_number_id +import kotlinx.android.synthetic.main.first_row.week_num +import kotlinx.android.synthetic.main.top_navigation.top_left_arrow +import kotlinx.android.synthetic.main.top_navigation.top_right_arrow +import kotlinx.android.synthetic.main.top_navigation.top_value import kotlinx.android.synthetic.main.widget_config_monthly.* import org.joda.time.DateTime @@ -217,7 +220,7 @@ class WidgetMonthlyConfigureActivity : SimpleActivity(), MonthlyCalendar { val weekendsTextColor = config.highlightWeekendsColor for (i in 0..6) { findViewById(resources.getIdentifier("label_$i", "id", packageName)).apply { - val textColor = if (config.highlightWeekends && isWeekend(i, config.isSundayFirst)) { + val textColor = if (config.highlightWeekends && context.isWeekendIndex(i)) { weekendsTextColor } else { mTextColor diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/dialogs/RepeatLimitTypePickerDialog.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/dialogs/RepeatLimitTypePickerDialog.kt index c53251ff2..b702c3733 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/dialogs/RepeatLimitTypePickerDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/dialogs/RepeatLimitTypePickerDialog.kt @@ -8,11 +8,11 @@ import com.simplemobiletools.calendar.pro.R import com.simplemobiletools.calendar.pro.extensions.config import com.simplemobiletools.calendar.pro.extensions.seconds import com.simplemobiletools.calendar.pro.helpers.Formatter +import com.simplemobiletools.calendar.pro.helpers.getJavaDayOfWeekFromJoda import com.simplemobiletools.calendar.pro.helpers.getNowSeconds import com.simplemobiletools.commons.extensions.* import kotlinx.android.synthetic.main.dialog_repeat_limit_type_picker.view.* import org.joda.time.DateTime -import java.util.* class RepeatLimitTypePickerDialog(val activity: Activity, var repeatLimit: Long, val startTS: Long, val callback: (repeatLimit: Long) -> Unit) { private var dialog: AlertDialog? = null @@ -88,13 +88,13 @@ class RepeatLimitTypePickerDialog(val activity: Activity, var repeatLimit: Long, private fun showRepetitionLimitDialog() { val repeatLimitDateTime = Formatter.getDateTimeFromTS(if (repeatLimit != 0L) repeatLimit else getNowSeconds()) - val datepicker = DatePickerDialog( + val datePicker = DatePickerDialog( activity, activity.getDatePickerDialogTheme(), repetitionLimitDateSetListener, repeatLimitDateTime.year, repeatLimitDateTime.monthOfYear - 1, repeatLimitDateTime.dayOfMonth ) - datepicker.datePicker.firstDayOfWeek = if (activity.config.isSundayFirst) Calendar.SUNDAY else Calendar.MONDAY - datepicker.show() + datePicker.datePicker.firstDayOfWeek = getJavaDayOfWeekFromJoda(activity.config.firstDayOfWeek) + datePicker.show() } private val repetitionLimitDateSetListener = DatePickerDialog.OnDateSetListener { v, year, monthOfYear, dayOfMonth -> diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/dialogs/RepeatRuleWeeklyDialog.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/dialogs/RepeatRuleWeeklyDialog.kt index 1521e0280..0ed99c1a3 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/dialogs/RepeatRuleWeeklyDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/dialogs/RepeatRuleWeeklyDialog.kt @@ -2,18 +2,18 @@ package com.simplemobiletools.calendar.pro.dialogs import android.app.Activity import com.simplemobiletools.calendar.pro.R -import com.simplemobiletools.calendar.pro.extensions.config +import com.simplemobiletools.calendar.pro.extensions.withFirstDayOfWeekToFront import com.simplemobiletools.commons.extensions.getAlertDialogBuilder import com.simplemobiletools.commons.extensions.setupDialogStuff import com.simplemobiletools.commons.views.MyAppCompatCheckbox -import kotlinx.android.synthetic.main.dialog_vertical_linear_layout.view.* +import kotlinx.android.synthetic.main.dialog_vertical_linear_layout.view.dialog_vertical_linear_layout class RepeatRuleWeeklyDialog(val activity: Activity, val curRepeatRule: Int, val callback: (repeatRule: Int) -> Unit) { private val view = activity.layoutInflater.inflate(R.layout.dialog_vertical_linear_layout, null) init { val days = activity.resources.getStringArray(R.array.week_days) - val checkboxes = ArrayList(7) + var checkboxes = ArrayList(7) for (i in 0..6) { val pow = Math.pow(2.0, i.toDouble()).toInt() (activity.layoutInflater.inflate(R.layout.my_checkbox, null) as MyAppCompatCheckbox).apply { @@ -24,10 +24,7 @@ class RepeatRuleWeeklyDialog(val activity: Activity, val curRepeatRule: Int, val } } - if (activity.config.isSundayFirst) { - checkboxes.add(0, checkboxes.removeAt(6)) - } - + checkboxes = activity.withFirstDayOfWeekToFront(checkboxes) checkboxes.forEach { view.dialog_vertical_linear_layout.addView(it) } diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/extensions/Context.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/extensions/Context.kt index e4ecdfafd..16f00e462 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/extensions/Context.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/extensions/Context.kt @@ -532,6 +532,7 @@ fun Context.getNewEventTimestampFromCode(dayCode: String, allowChangingDay: Bool val currMinutes = calendar.get(Calendar.MINUTE) dateTime.withMinuteOfHour(currMinutes).seconds() } + DEFAULT_START_TIME_NEXT_FULL_HOUR -> newDateTime.seconds() else -> { val hours = defaultStartTime / 60 @@ -692,11 +693,13 @@ fun Context.handleEventDeleting(eventIds: List, timestamps: List, ac eventsHelper.deleteRepeatingEventOccurrence(value, timestamps[index], true) } } + DELETE_FUTURE_OCCURRENCES -> { eventIds.forEachIndexed { index, value -> eventsHelper.addEventRepeatLimit(value, timestamps[index]) } } + DELETE_ALL_OCCURRENCES -> { eventsHelper.deleteEvents(eventIds.toMutableList(), true) } @@ -762,20 +765,88 @@ fun Context.getFirstDayOfWeek(date: DateTime): String { } fun Context.getFirstDayOfWeekDt(date: DateTime): DateTime { - var startOfWeek = date.withTimeAtStartOfDay() - if (!config.startWeekWithCurrentDay) { - startOfWeek = if (config.isSundayFirst) { - // a workaround for Joda-time's Monday-as-first-day-of-the-week - if (startOfWeek.dayOfWeek == DateTimeConstants.SUNDAY) { - startOfWeek - } else { - startOfWeek.minusWeeks(1).withDayOfWeek(DateTimeConstants.SUNDAY) - } + val currentDate = date.withTimeAtStartOfDay() + if (config.startWeekWithCurrentDay) { + return currentDate + } else { + val firstDayOfWeek = config.firstDayOfWeek + val currentDayOfWeek = currentDate.dayOfWeek + return if (currentDayOfWeek == firstDayOfWeek) { + currentDate } else { - startOfWeek.withDayOfWeek(DateTimeConstants.MONDAY) + // Joda-time's weeks always starts on Monday but user preferred firstDayOfWeek could be any week day + if (firstDayOfWeek < currentDayOfWeek) { + currentDate.withDayOfWeek(firstDayOfWeek) + } else { + currentDate.minusWeeks(1).withDayOfWeek(firstDayOfWeek) + } } } - return startOfWeek +} + +fun Context.getDayOfWeekString(dayOfWeek: Int): String { + val dayOfWeekResId = when (dayOfWeek) { + DateTimeConstants.MONDAY -> R.string.monday + DateTimeConstants.TUESDAY -> R.string.tuesday + DateTimeConstants.WEDNESDAY -> R.string.wednesday + DateTimeConstants.THURSDAY -> R.string.thursday + DateTimeConstants.FRIDAY -> R.string.friday + DateTimeConstants.SATURDAY -> R.string.saturday + DateTimeConstants.SUNDAY -> R.string.sunday + else -> throw IllegalArgumentException("Invalid day: $dayOfWeek") + } + + return getString(dayOfWeekResId) +} + +// format day bits to strings like "Mon, Tue, Wed" +fun Context.getShortDaysFromBitmask(bitMask: Int): String { + val dayBits = withFirstDayOfWeekToFront(listOf(MONDAY_BIT, TUESDAY_BIT, WEDNESDAY_BIT, THURSDAY_BIT, FRIDAY_BIT, SATURDAY_BIT, SUNDAY_BIT)) + val weekDays = withFirstDayOfWeekToFront(resources.getStringArray(R.array.week_days_short).toList()) + + var days = "" + dayBits.forEachIndexed { index, bit -> + if (bitMask and bit != 0) { + days += "${weekDays[index]}, " + } + } + + return days.trim().trimEnd(',') +} + +fun Context.withFirstDayOfWeekToFront(weekItems: Collection): ArrayList { + val firstDayOfWeek = config.firstDayOfWeek + if (firstDayOfWeek == DateTimeConstants.MONDAY) { + return weekItems.toMutableList() as ArrayList + } + + val firstDayOfWeekIndex = config.firstDayOfWeek - 1 + val rotatedWeekItems = weekItems.drop(firstDayOfWeekIndex) + weekItems.take(firstDayOfWeekIndex) + return rotatedWeekItems as ArrayList +} + +fun Context.getProperDayIndexInWeek(date: DateTime): Int { + val firstDayOfWeek = config.firstDayOfWeek + val dayOfWeek = date.dayOfWeek + val dayIndex = if (dayOfWeek >= firstDayOfWeek) { + dayOfWeek - firstDayOfWeek + } else { + dayOfWeek + (7 - firstDayOfWeek) + } + + return dayIndex +} + +fun Context.isWeekendIndex(dayIndex: Int): Boolean { + val firstDayOfWeek = config.firstDayOfWeek + val shiftedIndex = (dayIndex + firstDayOfWeek) % 7 + val dayOfWeek = if (shiftedIndex == 0) { + DateTimeConstants.SUNDAY + } else { + shiftedIndex + } + + return isWeekend(dayOfWeek) } fun Context.isTaskCompleted(event: Event): Boolean { diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/fragments/MonthDayFragment.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/fragments/MonthDayFragment.kt index 08ab41cbc..2d28c6bee 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/fragments/MonthDayFragment.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/fragments/MonthDayFragment.kt @@ -27,12 +27,11 @@ import com.simplemobiletools.commons.extensions.areSystemAnimationsEnabled import com.simplemobiletools.commons.extensions.beVisibleIf import com.simplemobiletools.commons.extensions.getProperTextColor import com.simplemobiletools.commons.interfaces.RefreshRecyclerViewListener -import kotlinx.android.synthetic.main.fragment_month_day.* +import kotlinx.android.synthetic.main.fragment_month_day.month_day_events_list import kotlinx.android.synthetic.main.fragment_month_day.view.* import org.joda.time.DateTime class MonthDayFragment : Fragment(), MonthlyCalendar, RefreshRecyclerViewListener { - private var mSundayFirst = false private var mShowWeekNumbers = false private var mDayCode = "" private var mSelectedDayCode = "" @@ -91,7 +90,6 @@ class MonthDayFragment : Fragment(), MonthlyCalendar, RefreshRecyclerViewListene private fun storeStateVariables() { mConfig.apply { - mSundayFirst = isSundayFirst mShowWeekNumbers = showWeekNumbers } } diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/fragments/MonthFragment.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/fragments/MonthFragment.kt index 63fa9b29f..fcddf17a8 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/fragments/MonthFragment.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/fragments/MonthFragment.kt @@ -24,13 +24,15 @@ import com.simplemobiletools.commons.extensions.applyColorFilter import com.simplemobiletools.commons.extensions.beGone import com.simplemobiletools.commons.extensions.beVisible import com.simplemobiletools.commons.extensions.getProperTextColor -import kotlinx.android.synthetic.main.fragment_month.view.* -import kotlinx.android.synthetic.main.top_navigation.view.* +import kotlinx.android.synthetic.main.fragment_month.view.month_calendar_holder +import kotlinx.android.synthetic.main.fragment_month.view.month_view_wrapper +import kotlinx.android.synthetic.main.top_navigation.view.top_left_arrow +import kotlinx.android.synthetic.main.top_navigation.view.top_right_arrow +import kotlinx.android.synthetic.main.top_navigation.view.top_value import org.joda.time.DateTime class MonthFragment : Fragment(), MonthlyCalendar { private var mTextColor = 0 - private var mSundayFirst = false private var mShowWeekNumbers = false private var mDayCode = "" private var mPackageName = "" @@ -80,7 +82,6 @@ class MonthFragment : Fragment(), MonthlyCalendar { private fun storeStateVariables() { mConfig.apply { - mSundayFirst = isSundayFirst mShowWeekNumbers = showWeekNumbers } } diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/fragments/WeekFragment.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/fragments/WeekFragment.kt index 681971e15..270134255 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/fragments/WeekFragment.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/fragments/WeekFragment.kt @@ -229,7 +229,7 @@ class WeekFragment : Fragment(), WeeklyCalendar { resources.getColor(R.color.theme_light_text_color) } else if (todayCode == dayCode) { primaryColor - } else if (highlightWeekends && isWeekend(curDay.dayOfWeek, true)) { + } else if (highlightWeekends && isWeekend(curDay.dayOfWeek)) { config.highlightWeekendsColor } else { requireContext().getProperTextColor() diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/fragments/YearFragment.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/fragments/YearFragment.kt index 32d8c7bfb..3d000d7e7 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/fragments/YearFragment.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/fragments/YearFragment.kt @@ -10,6 +10,7 @@ import androidx.fragment.app.Fragment import com.simplemobiletools.calendar.pro.R import com.simplemobiletools.calendar.pro.activities.MainActivity import com.simplemobiletools.calendar.pro.extensions.config +import com.simplemobiletools.calendar.pro.extensions.getProperDayIndexInWeek import com.simplemobiletools.calendar.pro.extensions.getViewBitmap import com.simplemobiletools.calendar.pro.extensions.printBitmap import com.simplemobiletools.calendar.pro.helpers.YEAR_LABEL @@ -22,13 +23,16 @@ import com.simplemobiletools.commons.extensions.applyColorFilter import com.simplemobiletools.commons.extensions.getProperPrimaryColor import com.simplemobiletools.commons.extensions.getProperTextColor import com.simplemobiletools.commons.extensions.updateTextColors -import kotlinx.android.synthetic.main.fragment_year.view.* -import kotlinx.android.synthetic.main.top_navigation.view.* +import kotlinx.android.synthetic.main.fragment_year.view.calendar_wrapper +import kotlinx.android.synthetic.main.fragment_year.view.month_2 +import kotlinx.android.synthetic.main.top_navigation.view.top_left_arrow +import kotlinx.android.synthetic.main.top_navigation.view.top_right_arrow +import kotlinx.android.synthetic.main.top_navigation.view.top_value import org.joda.time.DateTime class YearFragment : Fragment(), YearlyCalendar { private var mYear = 0 - private var mSundayFirst = false + private var mFirstDayOfWeek = 0 private var isPrintVersion = false private var lastHash = 0 private var mCalendar: YearlyCalendarImpl? = null @@ -50,14 +54,14 @@ class YearFragment : Fragment(), YearlyCalendar { override fun onPause() { super.onPause() - mSundayFirst = requireContext().config.isSundayFirst + mFirstDayOfWeek = requireContext().config.firstDayOfWeek } override fun onResume() { super.onResume() - val sundayFirst = requireContext().config.isSundayFirst - if (sundayFirst != mSundayFirst) { - mSundayFirst = sundayFirst + val firstDayOfWeek = requireContext().config.firstDayOfWeek + if (firstDayOfWeek != mFirstDayOfWeek) { + mFirstDayOfWeek = firstDayOfWeek setupMonths() } updateCalendar() @@ -76,11 +80,7 @@ class YearFragment : Fragment(), YearlyCalendar { for (i in 1..12) { val monthView = mView.findViewById(resources.getIdentifier("month_$i", "id", requireContext().packageName)) - var dayOfWeek = dateTime.withMonthOfYear(i).dayOfWeek().get() - if (!mSundayFirst) { - dayOfWeek-- - } - + val dayOfWeek = requireContext().getProperDayIndexInWeek(dateTime.withMonthOfYear(i)) val monthLabel = mView.findViewById(resources.getIdentifier("month_${i}_label", "id", requireContext().packageName)) val curTextColor = when { isPrintVersion -> resources.getColor(R.color.theme_light_text_color) diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/helpers/Config.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/helpers/Config.kt index 40628dfa6..a5e260ffd 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/helpers/Config.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/helpers/Config.kt @@ -29,6 +29,13 @@ class Config(context: Context) : BaseConfig(context) { get() = prefs.getBoolean(START_WEEK_WITH_CURRENT_DAY, false) set(startWeekWithCurrentDay) = prefs.edit().putBoolean(START_WEEK_WITH_CURRENT_DAY, startWeekWithCurrentDay).apply() + var firstDayOfWeek: Int + get() { + val defaultFirstDayOfWeek = Calendar.getInstance(Locale.getDefault()).firstDayOfWeek + return prefs.getInt(FIRST_DAY_OF_WEEK, getJodaDayOfWeekFromJava(defaultFirstDayOfWeek)) + } + set(firstDayOfWeek) = prefs.edit().putInt(FIRST_DAY_OF_WEEK, firstDayOfWeek).apply() + var showMidnightSpanningEventsAtTop: Boolean get() = prefs.getBoolean(SHOW_MIDNIGHT_SPANNING_EVENTS_AT_TOP, true) set(midnightSpanning) = prefs.edit().putBoolean(SHOW_MIDNIGHT_SPANNING_EVENTS_AT_TOP, midnightSpanning).apply() diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/helpers/Constants.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/helpers/Constants.kt index 255a2f165..8463bdd97 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/helpers/Constants.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/helpers/Constants.kt @@ -4,7 +4,9 @@ import com.simplemobiletools.calendar.pro.activities.EventActivity import com.simplemobiletools.calendar.pro.activities.TaskActivity import com.simplemobiletools.commons.helpers.MONTH_SECONDS import org.joda.time.DateTime -import java.util.* +import org.joda.time.DateTimeConstants +import java.util.Calendar +import java.util.UUID const val STORED_LOCALLY_ONLY = 0 const val ROW_COUNT = 6 @@ -82,6 +84,7 @@ const val EVENT_LIST_PERIOD = "event_list_period" const val WEEK_NUMBERS = "week_numbers" const val START_WEEKLY_AT = "start_weekly_at" const val START_WEEK_WITH_CURRENT_DAY = "start_week_with_current_day" +const val FIRST_DAY_OF_WEEK = "first_day_of_week" const val SHOW_MIDNIGHT_SPANNING_EVENTS_AT_TOP = "show_midnight_spanning_events_at_top" const val ALLOW_CUSTOMIZE_DAY_COUNT = "allow_customise_day_count" const val VIBRATE = "vibrate" @@ -266,12 +269,9 @@ const val ACTION_MARK_COMPLETED = "ACTION_MARK_COMPLETED" fun getNowSeconds() = System.currentTimeMillis() / 1000L -fun isWeekend(i: Int, isSundayFirst: Boolean): Boolean { - return if (isSundayFirst) { - i == 0 || i == 6 || i == 7 || i == 13 - } else { - i == 5 || i == 6 || i == 12 || i == 13 - } +fun isWeekend(dayOfWeek: Int): Boolean { + val weekendDays = listOf(DateTimeConstants.SATURDAY, DateTimeConstants.SUNDAY) + return dayOfWeek in weekendDays } fun getActivityToOpen(isTask: Boolean) = if (isTask) { @@ -299,3 +299,29 @@ fun getPreviousAutoBackupTime(): DateTime { val nextBackupTime = getNextAutoBackupTime() return nextBackupTime.minusDays(AUTO_BACKUP_INTERVAL_IN_DAYS) } + +fun getJodaDayOfWeekFromJava(dayOfWeek: Int): Int { + return when (dayOfWeek) { + Calendar.SUNDAY -> DateTimeConstants.SUNDAY + Calendar.MONDAY -> DateTimeConstants.MONDAY + Calendar.TUESDAY -> DateTimeConstants.TUESDAY + Calendar.WEDNESDAY -> DateTimeConstants.WEDNESDAY + Calendar.THURSDAY -> DateTimeConstants.THURSDAY + Calendar.FRIDAY -> DateTimeConstants.FRIDAY + Calendar.SATURDAY -> DateTimeConstants.SATURDAY + else -> throw IllegalArgumentException("Invalid day: $dayOfWeek") + } +} + +fun getJavaDayOfWeekFromJoda(dayOfWeek: Int): Int { + return when (dayOfWeek) { + DateTimeConstants.SUNDAY -> Calendar.SUNDAY + DateTimeConstants.MONDAY -> Calendar.MONDAY + DateTimeConstants.TUESDAY -> Calendar.TUESDAY + DateTimeConstants.WEDNESDAY -> Calendar.WEDNESDAY + DateTimeConstants.THURSDAY -> Calendar.THURSDAY + DateTimeConstants.FRIDAY -> Calendar.FRIDAY + DateTimeConstants.SATURDAY -> Calendar.SATURDAY + else -> throw IllegalArgumentException("Invalid day: $dayOfWeek") + } +} diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/helpers/MonthlyCalendarImpl.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/helpers/MonthlyCalendarImpl.kt index 6a707d4ce..cc66c6e21 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/helpers/MonthlyCalendarImpl.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/helpers/MonthlyCalendarImpl.kt @@ -1,8 +1,9 @@ package com.simplemobiletools.calendar.pro.helpers import android.content.Context -import com.simplemobiletools.calendar.pro.extensions.config import com.simplemobiletools.calendar.pro.extensions.eventsHelper +import com.simplemobiletools.calendar.pro.extensions.getProperDayIndexInWeek +import com.simplemobiletools.calendar.pro.extensions.isWeekendIndex import com.simplemobiletools.calendar.pro.extensions.seconds import com.simplemobiletools.calendar.pro.interfaces.MonthlyCalendar import com.simplemobiletools.calendar.pro.models.DayMonthly @@ -34,13 +35,10 @@ class MonthlyCalendarImpl(val callback: MonthlyCalendar, val context: Context) { fun getDays(markDaysWithEvents: Boolean) { val days = ArrayList(DAYS_CNT) - val currMonthDays = mTargetDate.dayOfMonth().maximumValue - var firstDayIndex = mTargetDate.withDayOfMonth(1).dayOfWeek - val isSundayFirst = context.config.isSundayFirst - if (!isSundayFirst) { - firstDayIndex -= 1 - } + val firstDayOfMonth = mTargetDate.withDayOfMonth(1) + val firstDayIndex = context.getProperDayIndexInWeek(firstDayOfMonth) + val currMonthDays = mTargetDate.dayOfMonth().maximumValue val prevMonthDays = mTargetDate.minusMonths(1).dayOfMonth().maximumValue var isThisMonth = false @@ -70,7 +68,7 @@ class MonthlyCalendarImpl(val callback: MonthlyCalendar, val context: Context) { val newDay = curDay.withDayOfMonth(value) val dayCode = Formatter.getDayCodeFromDateTime(newDay) - val day = DayMonthly(value, isThisMonth, isToday, dayCode, newDay.weekOfWeekyear, ArrayList(), i, isWeekend(i % 7, isSundayFirst)) + val day = DayMonthly(value, isThisMonth, isToday, dayCode, newDay.weekOfWeekyear, ArrayList(), i, context.isWeekendIndex(i)) days.add(day) value++ } diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/helpers/MyWidgetMonthlyProvider.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/helpers/MyWidgetMonthlyProvider.kt index 941a33af2..ac2d8ccc7 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/helpers/MyWidgetMonthlyProvider.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/helpers/MyWidgetMonthlyProvider.kt @@ -14,6 +14,7 @@ import com.simplemobiletools.calendar.pro.R import com.simplemobiletools.calendar.pro.activities.SplashActivity import com.simplemobiletools.calendar.pro.extensions.config import com.simplemobiletools.calendar.pro.extensions.getWidgetFontSize +import com.simplemobiletools.calendar.pro.extensions.isWeekendIndex import com.simplemobiletools.calendar.pro.extensions.launchNewEventOrTaskActivity import com.simplemobiletools.calendar.pro.interfaces.MonthlyCalendar import com.simplemobiletools.calendar.pro.models.DayMonthly @@ -21,6 +22,7 @@ import com.simplemobiletools.calendar.pro.models.Event import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.helpers.MEDIUM_ALPHA import org.joda.time.DateTime +import org.joda.time.DateTimeConstants class MyWidgetMonthlyProvider : AppWidgetProvider() { private val PREV = "prev" @@ -233,14 +235,14 @@ class MyWidgetMonthlyProvider : AppWidgetProvider() { private fun updateDayLabels(context: Context, views: RemoteViews, resources: Resources, textColor: Int) { val config = context.config - val sundayFirst = config.isSundayFirst + val firstDayOfWeek = config.firstDayOfWeek val smallerFontSize = context.getWidgetFontSize() val packageName = context.packageName val letters = context.resources.getStringArray(R.array.week_day_letters) for (i in 0..6) { val id = resources.getIdentifier("label_$i", "id", packageName) - val dayTextColor = if (context.config.highlightWeekends && isWeekend(i, sundayFirst)) { + val dayTextColor = if (context.config.highlightWeekends && context.isWeekendIndex(i)) { context.config.highlightWeekendsColor } else { textColor @@ -250,8 +252,8 @@ class MyWidgetMonthlyProvider : AppWidgetProvider() { views.setTextSize(id, smallerFontSize) var index = i - if (sundayFirst) { - index = (index + 6) % letters.size + if (firstDayOfWeek != DateTimeConstants.MONDAY) { + index = (index + firstDayOfWeek - 1) % 7 } views.setText(id, letters[index]) diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/views/MonthView.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/views/MonthView.kt index 1d73518cc..4d0e8899f 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/views/MonthView.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/views/MonthView.kt @@ -8,12 +8,10 @@ import android.util.AttributeSet import android.util.SparseIntArray import android.view.View import com.simplemobiletools.calendar.pro.R -import com.simplemobiletools.calendar.pro.extensions.config -import com.simplemobiletools.calendar.pro.extensions.seconds +import com.simplemobiletools.calendar.pro.extensions.* import com.simplemobiletools.calendar.pro.helpers.COLUMN_COUNT import com.simplemobiletools.calendar.pro.helpers.Formatter import com.simplemobiletools.calendar.pro.helpers.ROW_COUNT -import com.simplemobiletools.calendar.pro.helpers.isWeekend import com.simplemobiletools.calendar.pro.models.DayMonthly import com.simplemobiletools.calendar.pro.models.Event import com.simplemobiletools.calendar.pro.models.MonthViewEvent @@ -231,7 +229,7 @@ class MonthView(context: Context, attrs: AttributeSet, defStyle: Int) : View(con var weekDayLetterPaint = textPaint if (i == currDayOfWeek && !isPrintVersion) { weekDayLetterPaint = getColoredPaint(primaryColor) - } else if (highlightWeekends && isWeekend(i, config.isSundayFirst)) { + } else if (highlightWeekends && context.isWeekendIndex(i)) { weekDayLetterPaint = getColoredPaint(weekendsTextColor) } canvas.drawText(dayLetters[i], xPos, weekDaysLetterHeight * 0.7f, weekDayLetterPaint) @@ -393,10 +391,7 @@ class MonthView(context: Context, attrs: AttributeSet, defStyle: Int) : View(con } private fun initWeekDayLetters() { - dayLetters = context.resources.getStringArray(R.array.week_day_letters).toMutableList() as ArrayList - if (config.isSundayFirst) { - dayLetters.moveLastItemToFront() - } + dayLetters = context.withFirstDayOfWeekToFront(context.resources.getStringArray(R.array.week_day_letters).toList()) } private fun setupCurrentDayOfWeekIndex() { @@ -405,12 +400,7 @@ class MonthView(context: Context, attrs: AttributeSet, defStyle: Int) : View(con return } - currDayOfWeek = DateTime().dayOfWeek - if (config.isSundayFirst) { - currDayOfWeek %= 7 - } else { - currDayOfWeek-- - } + currDayOfWeek = context.getProperDayIndexInWeek(DateTime()) } // take into account cases when an event starts on the previous screen, subtract those days diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/views/SmallMonthView.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/views/SmallMonthView.kt index d4945e161..2edc5121b 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/views/SmallMonthView.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/views/SmallMonthView.kt @@ -8,7 +8,7 @@ import android.util.AttributeSet import android.view.View import com.simplemobiletools.calendar.pro.R import com.simplemobiletools.calendar.pro.extensions.config -import com.simplemobiletools.calendar.pro.helpers.isWeekend +import com.simplemobiletools.calendar.pro.extensions.isWeekendIndex import com.simplemobiletools.calendar.pro.models.DayYearly import com.simplemobiletools.commons.extensions.adjustAlpha import com.simplemobiletools.commons.extensions.getProperPrimaryColor @@ -25,7 +25,6 @@ class SmallMonthView(context: Context, attrs: AttributeSet, defStyle: Int) : Vie private var days = 31 private var isLandscape = false private var highlightWeekends = false - private var isSundayFirst = false private var isPrintVersion = false private var mEvents: ArrayList? = null @@ -61,7 +60,6 @@ class SmallMonthView(context: Context, attrs: AttributeSet, defStyle: Int) : Vie textColor = baseColor.adjustAlpha(MEDIUM_ALPHA) weekendsTextColor = context.config.highlightWeekendsColor.adjustAlpha(MEDIUM_ALPHA) highlightWeekends = context.config.highlightWeekends - isSundayFirst = context.config.isSundayFirst paint = Paint(Paint.ANTI_ALIAS_FLAG).apply { color = textColor @@ -107,7 +105,7 @@ class SmallMonthView(context: Context, attrs: AttributeSet, defStyle: Int) : Vie val curPaint = Paint(paint) curPaint.color = colors.first() return curPaint - } else if (highlightWeekends && isWeekend(weekDay - 1, isSundayFirst)) { + } else if (highlightWeekends && context.isWeekendIndex(weekDay - 1)) { val curPaint = Paint(paint) curPaint.color = weekendsTextColor return curPaint diff --git a/app/src/main/res/layout/activity_settings.xml b/app/src/main/res/layout/activity_settings.xml index 0fa295391..07667a447 100644 --- a/app/src/main/res/layout/activity_settings.xml +++ b/app/src/main/res/layout/activity_settings.xml @@ -148,6 +148,29 @@ + + + + + + + + - - - - - -