From 3d56751b18ff08cf0c42250844538b4f508b708f Mon Sep 17 00:00:00 2001 From: Naveen Date: Sat, 8 Apr 2023 17:03:36 +0530 Subject: [PATCH] Allow changing CalDAV event color --- .../calendar/pro/activities/EventActivity.kt | 30 +++++++++- .../pro/dialogs/EditEventTypeDialog.kt | 2 +- .../pro/dialogs/SelectEventTypeColorDialog.kt | 23 +++++--- .../calendar/pro/fragments/WeekFragment.kt | 8 ++- .../calendar/pro/helpers/CalDAVHelper.kt | 46 +++++++-------- .../calendar/pro/helpers/EventsHelper.kt | 5 +- app/src/main/res/layout/activity_event.xml | 57 ++++++++++++++++++- 7 files changed, 133 insertions(+), 38 deletions(-) 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 b5dc7156c..d6bacc8ab 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 @@ -10,6 +10,7 @@ import android.graphics.drawable.LayerDrawable import android.net.Uri import android.os.Bundle import android.provider.CalendarContract.Attendees +import android.provider.CalendarContract.Colors import android.provider.ContactsContract.CommonDataKinds import android.provider.ContactsContract.CommonDataKinds.StructuredName import android.provider.ContactsContract.Data @@ -825,6 +826,19 @@ class EventActivity : SimpleActivity() { } } + private fun showEventColorDialog() { + hideKeyboard() + ensureBackgroundThread { + val eventType = eventsHelper.getEventTypeWithCalDAVCalendarId(calendarId = mEventCalendarId)!! + runOnUiThread { + SelectEventTypeColorDialog(activity = this, eventType = eventType, selectedColor = mEvent.color, colorType = Colors.TYPE_EVENT) { color -> + mEvent.color = color + event_caldav_color.setFillWithStroke(color, getProperBackgroundColor()) + } + } + } + } + private fun checkReminderTexts() { updateReminder1Text() updateReminder2Text() @@ -936,6 +950,9 @@ class EventActivity : SimpleActivity() { event_caldav_calendar_image.beVisible() event_caldav_calendar_holder.beVisible() event_caldav_calendar_divider.beVisible() + event_caldav_color_image.beVisible() + event_caldav_color_holder.beVisible() + event_caldav_color_divider.beVisible() val calendars = calDAVHelper.getCalDAVCalendars("", true).filter { it.canWrite() && config.getSyncedCalendarIdsAsList().contains(it.id) @@ -959,6 +976,7 @@ class EventActivity : SimpleActivity() { updateAvailabilityImage() } } + event_caldav_color_holder.setOnClickListener { showEventColorDialog() } } else { updateCurrentCalendarInfo(null) } @@ -974,6 +992,9 @@ class EventActivity : SimpleActivity() { event_caldav_calendar_divider.beVisibleIf(currentCalendar == null) event_caldav_calendar_email.beGoneIf(currentCalendar == null) event_caldav_calendar_color.beGoneIf(currentCalendar == null) + event_caldav_color_image.beGoneIf(currentCalendar == null) + event_caldav_color_holder.beGoneIf(currentCalendar == null) + event_caldav_color_divider.beGoneIf(currentCalendar == null) if (currentCalendar == null) { mEventCalendarId = STORED_LOCALLY_ONLY @@ -1002,6 +1023,13 @@ class EventActivity : SimpleActivity() { event_caldav_calendar_holder.apply { setPadding(paddingLeft, 0, paddingRight, 0) } + + val eventColor = if (mEvent.color == 0) { + calendarColor + } else { + mEvent.color + } + event_caldav_color.setFillWithStroke(eventColor, getProperBackgroundColor()) } } } @@ -1791,7 +1819,7 @@ class EventActivity : SimpleActivity() { val textColor = getProperTextColor() arrayOf( event_time_image, event_time_zone_image, event_repetition_image, event_reminder_image, event_type_image, event_caldav_calendar_image, - event_reminder_1_type, event_reminder_2_type, event_reminder_3_type, event_attendees_image, event_availability_image + event_reminder_1_type, event_reminder_2_type, event_reminder_3_type, event_attendees_image, event_availability_image, event_caldav_color_image ).forEach { it.applyColorFilter(textColor) } diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/dialogs/EditEventTypeDialog.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/dialogs/EditEventTypeDialog.kt index 0133c3d2f..6bf3d3fb9 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/dialogs/EditEventTypeDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/dialogs/EditEventTypeDialog.kt @@ -32,7 +32,7 @@ class EditEventTypeDialog(val activity: Activity, var eventType: EventType? = nu } } } else { - SelectEventTypeColorDialog(activity, eventType!!) { + SelectEventTypeColorDialog(activity, eventType!!, eventType!!.color) { eventType!!.color = it setupColor(type_color) } diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/dialogs/SelectEventTypeColorDialog.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/dialogs/SelectEventTypeColorDialog.kt index bc451de2d..27e560e77 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/dialogs/SelectEventTypeColorDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/dialogs/SelectEventTypeColorDialog.kt @@ -1,6 +1,7 @@ package com.simplemobiletools.calendar.pro.dialogs import android.app.Activity +import android.provider.CalendarContract.Colors import android.view.ViewGroup import android.widget.RadioButton import android.widget.RadioGroup @@ -16,11 +17,17 @@ import com.simplemobiletools.commons.extensions.setupDialogStuff import kotlinx.android.synthetic.main.dialog_select_event_type_color.view.* import kotlinx.android.synthetic.main.radio_button_with_color.view.* -class SelectEventTypeColorDialog(val activity: Activity, val eventType: EventType, val callback: (color: Int) -> Unit) { +class SelectEventTypeColorDialog( + val activity: Activity, + val eventType: EventType, + val selectedColor: Int, + val colorType: Int = Colors.TYPE_CALENDAR, + val callback: (color: Int) -> Unit +) { private var dialog: AlertDialog? = null private val radioGroup: RadioGroup private var wasInit = false - private val colors = activity.calDAVHelper.getAvailableCalDAVCalendarColors(eventType) + private val colors = activity.calDAVHelper.getAvailableCalDAVCalendarColors(eventType, colorType) init { val view = activity.layoutInflater.inflate(R.layout.dialog_select_event_type_color, null) as ViewGroup @@ -29,8 +36,8 @@ class SelectEventTypeColorDialog(val activity: Activity, val eventType: EventTyp showCustomColorPicker() } - colors.forEachIndexed { index, value -> - addRadioButton(index, value) + colors.forEach { (color, key) -> + addRadioButton(key.toInt(), color) } wasInit = true @@ -50,22 +57,22 @@ class SelectEventTypeColorDialog(val activity: Activity, val eventType: EventTyp val view = activity.layoutInflater.inflate(R.layout.radio_button_with_color, null) (view.dialog_radio_button as RadioButton).apply { text = if (color == 0) activity.getString(R.string.transparent) else String.format("#%06X", 0xFFFFFF and color) - isChecked = color == eventType.color + isChecked = color == selectedColor id = colorKey } view.dialog_radio_color.setFillWithStroke(color, activity.getProperBackgroundColor()) view.setOnClickListener { - viewClicked(colorKey) + viewClicked(color) } radioGroup.addView(view, RadioGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)) } - private fun viewClicked(colorKey: Int) { + private fun viewClicked(color: Int) { if (!wasInit) return - callback(colors[colorKey]) + callback(color) dialog?.dismiss() } 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 45e3be372..7418548a9 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 @@ -557,9 +557,13 @@ class WeekFragment : Fragment(), WeeklyCalendar { val dayColumn = dayColumns[dayOfWeek] (inflater.inflate(R.layout.week_event_marker, null, false) as ConstraintLayout).apply { - var backgroundColor = eventTypeColors.get(event.eventType, primaryColor) + var backgroundColor = if (event.color == 0) { + eventTypeColors.get(event.eventType, primaryColor) + } else { + event.color + } var textColor = backgroundColor.getContrastColor() - val currentEventWeeklyView = eventTimeRanges[currentDayCode]!!.get(event.id) + val currentEventWeeklyView = eventTimeRanges[currentDayCode]!![event.id] val adjustAlpha = if (event.isTask()) { dimCompletedTasks && event.isTaskCompleted() diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/helpers/CalDAVHelper.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/helpers/CalDAVHelper.kt index adc41c6af..edb8a3d8c 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/helpers/CalDAVHelper.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/helpers/CalDAVHelper.kt @@ -5,7 +5,6 @@ import android.content.ContentUris import android.content.ContentValues import android.content.Context import android.provider.CalendarContract.* -import android.util.SparseIntArray import android.widget.Toast import com.google.gson.Gson import com.google.gson.reflect.TypeToken @@ -116,35 +115,25 @@ class CalDAVHelper(val context: Context) { private fun getCalDAVColorKey(eventType: EventType): String? { val colors = getAvailableCalDAVCalendarColors(eventType) - val colorKey = colors.indexOf(eventType.color) - return if (colorKey > 0) { - colorKey.toString() - } else { - null - } + return colors[eventType.color] } @SuppressLint("MissingPermission") - fun getAvailableCalDAVCalendarColors(eventType: EventType): ArrayList { - val colors = SparseIntArray() + fun getAvailableCalDAVCalendarColors(eventType: EventType, colorType: Int = Colors.TYPE_CALENDAR): Map { + val colors = mutableMapOf() val uri = Colors.CONTENT_URI val projection = arrayOf(Colors.COLOR, Colors.COLOR_KEY) val selection = "${Colors.COLOR_TYPE} = ? AND ${Colors.ACCOUNT_NAME} = ?" - val selectionArgs = arrayOf(Colors.TYPE_CALENDAR.toString(), eventType.caldavEmail) + val selectionArgs = arrayOf(colorType.toString(), eventType.caldavEmail) context.queryCursor(uri, projection, selection, selectionArgs) { cursor -> - val colorKey = cursor.getIntValue(Colors.COLOR_KEY) + val colorKey = cursor.getStringValue(Colors.COLOR_KEY) val color = cursor.getIntValue(Colors.COLOR) - colors.put(colorKey, color) + colors[colorKey] = color } - var sortedColors = ArrayList(colors.size()) - (0 until colors.size()).mapTo(sortedColors) { colors[it] } - if (sortedColors.isNotEmpty()) { - sortedColors = sortedColors.distinct() as ArrayList - } - - return sortedColors + return colors.toSortedMap().entries + .associate { (k, v) -> v to k } } @SuppressLint("MissingPermission") @@ -181,7 +170,8 @@ class CalDAVHelper(val context: Context) { Events.EVENT_TIMEZONE, Events.CALENDAR_TIME_ZONE, Events.DELETED, - Events.AVAILABILITY + Events.AVAILABILITY, + Events.EVENT_COLOR ) val selection = "${Events.CALENDAR_ID} = $calendarId" @@ -210,6 +200,7 @@ class CalDAVHelper(val context: Context) { val reminders = getCalDAVEventReminders(id) val attendees = Gson().toJson(getCalDAVEventAttendees(id)) val availability = cursor.getIntValue(Events.AVAILABILITY) + val color = cursor.getIntValue(Events.EVENT_COLOR) if (endTS == 0L) { val duration = cursor.getStringValue(Events.DURATION) ?: "" @@ -230,7 +221,8 @@ class CalDAVHelper(val context: Context) { reminder2?.minutes ?: REMINDER_OFF, reminder3?.minutes ?: REMINDER_OFF, reminder1?.type ?: REMINDER_NOTIFICATION, reminder2?.type ?: REMINDER_NOTIFICATION, reminder3?.type ?: REMINDER_NOTIFICATION, repeatRule.repeatInterval, repeatRule.repeatRule, - repeatRule.repeatLimit, ArrayList(), attendees, importId, eventTimeZone, allDay, eventTypeId, source = source, availability = availability + repeatRule.repeatLimit, ArrayList(), attendees, importId, eventTimeZone, allDay, eventTypeId, + source = source, availability = availability, color = color ) if (event.getIsAllDay()) { @@ -291,7 +283,6 @@ class CalDAVHelper(val context: Context) { existingEvent.apply { this.id = null - color = 0 lastUpdated = 0L repetitionExceptions = ArrayList() } @@ -394,14 +385,23 @@ class CalDAVHelper(val context: Context) { } private fun fillEventContentValues(event: Event): ContentValues { + val calendarId = event.getCalDAVCalendarId() return ContentValues().apply { - put(Events.CALENDAR_ID, event.getCalDAVCalendarId()) + put(Events.CALENDAR_ID, calendarId) put(Events.TITLE, event.title) put(Events.DESCRIPTION, event.description) put(Events.EVENT_LOCATION, event.location) put(Events.STATUS, Events.STATUS_CONFIRMED) put(Events.AVAILABILITY, event.availability) + val eventType = eventsHelper.getEventTypeWithCalDAVCalendarId(calendarId)!! + val colors = getAvailableCalDAVCalendarColors(eventType, Colors.TYPE_EVENT) + if (event.color == 0) { + put(Events.EVENT_COLOR_KEY, "") + } else { + put(Events.EVENT_COLOR_KEY, colors[event.color]) + } + val repeatRule = Parser().getRepeatCode(event) if (repeatRule.isEmpty()) { putNull(Events.RRULE) diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/helpers/EventsHelper.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/helpers/EventsHelper.kt index 31c635149..fc9327c71 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/helpers/EventsHelper.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/helpers/EventsHelper.kt @@ -337,7 +337,10 @@ class EventsHelper(val context: Context) { } } } - it.color = eventTypeColors.get(it.eventType) ?: context.getProperPrimaryColor() + + if (it.color == 0) { + it.color = eventTypeColors.get(it.eventType) ?: context.getProperPrimaryColor() + } } callback(events) diff --git a/app/src/main/res/layout/activity_event.xml b/app/src/main/res/layout/activity_event.xml index c467c41ef..7a4a229b1 100644 --- a/app/src/main/res/layout/activity_event.xml +++ b/app/src/main/res/layout/activity_event.xml @@ -507,10 +507,63 @@ android:importantForAccessibility="no" /> + + + + + + + + + + + +