mirror of
https://github.com/SimpleMobileTools/Simple-Calendar.git
synced 2025-06-05 21:59:17 +02:00
Merge pull request #2116 from Naveen3Singh/recurring_event_edit_fix
Properly handle `Update the selected occurrence only`
This commit is contained in:
@@ -1155,7 +1155,7 @@ class EventActivity : SimpleActivity() {
|
|||||||
DeleteEventDialog(this, arrayListOf(mEvent.id!!), mEvent.repeatInterval > 0) {
|
DeleteEventDialog(this, arrayListOf(mEvent.id!!), mEvent.repeatInterval > 0) {
|
||||||
ensureBackgroundThread {
|
ensureBackgroundThread {
|
||||||
when (it) {
|
when (it) {
|
||||||
DELETE_SELECTED_OCCURRENCE -> eventsHelper.addEventRepetitionException(mEvent.id!!, mEventOccurrenceTS, true)
|
DELETE_SELECTED_OCCURRENCE -> eventsHelper.deleteRepeatingEventOccurrence(mEvent.id!!, mEventOccurrenceTS, true)
|
||||||
DELETE_FUTURE_OCCURRENCES -> eventsHelper.addEventRepeatLimit(mEvent.id!!, mEventOccurrenceTS)
|
DELETE_FUTURE_OCCURRENCES -> eventsHelper.addEventRepeatLimit(mEvent.id!!, mEventOccurrenceTS)
|
||||||
DELETE_ALL_OCCURRENCES -> eventsHelper.deleteEvent(mEvent.id!!, true)
|
DELETE_ALL_OCCURRENCES -> eventsHelper.deleteEvent(mEvent.id!!, true)
|
||||||
}
|
}
|
||||||
@@ -1361,7 +1361,6 @@ class EventActivity : SimpleActivity() {
|
|||||||
when (it) {
|
when (it) {
|
||||||
EDIT_SELECTED_OCCURRENCE -> {
|
EDIT_SELECTED_OCCURRENCE -> {
|
||||||
ensureBackgroundThread {
|
ensureBackgroundThread {
|
||||||
eventsHelper.addEventRepetitionException(mEvent.id!!, mEventOccurrenceTS, true)
|
|
||||||
mEvent.apply {
|
mEvent.apply {
|
||||||
parentId = id!!.toLong()
|
parentId = id!!.toLong()
|
||||||
id = null
|
id = null
|
||||||
@@ -1370,7 +1369,7 @@ class EventActivity : SimpleActivity() {
|
|||||||
repeatLimit = 0
|
repeatLimit = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
eventsHelper.insertEvent(mEvent, true, true) {
|
eventsHelper.insertEvent(mEvent, addToCalDAV = true, showToasts = true) {
|
||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -474,7 +474,6 @@ class TaskActivity : SimpleActivity() {
|
|||||||
when (it) {
|
when (it) {
|
||||||
EDIT_SELECTED_OCCURRENCE -> {
|
EDIT_SELECTED_OCCURRENCE -> {
|
||||||
ensureBackgroundThread {
|
ensureBackgroundThread {
|
||||||
eventsHelper.addEventRepetitionException(mTask.id!!, mTaskOccurrenceTS, addToCalDAV = false)
|
|
||||||
mTask.apply {
|
mTask.apply {
|
||||||
parentId = id!!.toLong()
|
parentId = id!!.toLong()
|
||||||
id = null
|
id = null
|
||||||
@@ -533,9 +532,9 @@ class TaskActivity : SimpleActivity() {
|
|||||||
DeleteEventDialog(this, arrayListOf(mTask.id!!), mTask.repeatInterval > 0, isTask = true) {
|
DeleteEventDialog(this, arrayListOf(mTask.id!!), mTask.repeatInterval > 0, isTask = true) {
|
||||||
ensureBackgroundThread {
|
ensureBackgroundThread {
|
||||||
when (it) {
|
when (it) {
|
||||||
DELETE_SELECTED_OCCURRENCE -> eventsHelper.addEventRepetitionException(mTask.id!!, mTaskOccurrenceTS, true)
|
DELETE_SELECTED_OCCURRENCE -> eventsHelper.deleteRepeatingEventOccurrence(mTask.id!!, mTaskOccurrenceTS, false)
|
||||||
DELETE_FUTURE_OCCURRENCES -> eventsHelper.addEventRepeatLimit(mTask.id!!, mTaskOccurrenceTS)
|
DELETE_FUTURE_OCCURRENCES -> eventsHelper.addEventRepeatLimit(mTask.id!!, mTaskOccurrenceTS)
|
||||||
DELETE_ALL_OCCURRENCES -> eventsHelper.deleteEvent(mTask.id!!, true)
|
DELETE_ALL_OCCURRENCES -> eventsHelper.deleteEvent(mTask.id!!, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
runOnUiThread {
|
runOnUiThread {
|
||||||
|
@@ -697,7 +697,7 @@ fun Context.handleEventDeleting(eventIds: List<Long>, timestamps: List<Long>, ac
|
|||||||
when (action) {
|
when (action) {
|
||||||
DELETE_SELECTED_OCCURRENCE -> {
|
DELETE_SELECTED_OCCURRENCE -> {
|
||||||
eventIds.forEachIndexed { index, value ->
|
eventIds.forEachIndexed { index, value ->
|
||||||
eventsHelper.addEventRepetitionException(value, timestamps[index], true)
|
eventsHelper.deleteRepeatingEventOccurrence(value, timestamps[index], true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DELETE_FUTURE_OCCURRENCES -> {
|
DELETE_FUTURE_OCCURRENCES -> {
|
||||||
|
@@ -185,6 +185,7 @@ class CalDAVHelper(val context: Context) {
|
|||||||
Events.CALENDAR_TIME_ZONE,
|
Events.CALENDAR_TIME_ZONE,
|
||||||
Events.DELETED,
|
Events.DELETED,
|
||||||
Events.AVAILABILITY,
|
Events.AVAILABILITY,
|
||||||
|
Events.STATUS,
|
||||||
Events.EVENT_COLOR
|
Events.EVENT_COLOR
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -214,6 +215,7 @@ class CalDAVHelper(val context: Context) {
|
|||||||
val reminders = getCalDAVEventReminders(id)
|
val reminders = getCalDAVEventReminders(id)
|
||||||
val attendees = Gson().toJson(getCalDAVEventAttendees(id))
|
val attendees = Gson().toJson(getCalDAVEventAttendees(id))
|
||||||
val availability = cursor.getIntValue(Events.AVAILABILITY)
|
val availability = cursor.getIntValue(Events.AVAILABILITY)
|
||||||
|
val status = cursor.getIntValue(Events.STATUS)
|
||||||
val color = cursor.getIntValueOrNull(Events.EVENT_COLOR)
|
val color = cursor.getIntValueOrNull(Events.EVENT_COLOR)
|
||||||
val displayColor = if (color != null) {
|
val displayColor = if (color != null) {
|
||||||
getDisplayColorFromColor(color)
|
getDisplayColorFromColor(color)
|
||||||
@@ -255,14 +257,28 @@ class CalDAVHelper(val context: Context) {
|
|||||||
val parentImportId = "$source-$originalId"
|
val parentImportId = "$source-$originalId"
|
||||||
val parentEvent = context.eventsDB.getEventWithImportId(parentImportId)
|
val parentEvent = context.eventsDB.getEventWithImportId(parentImportId)
|
||||||
val originalDayCode = Formatter.getDayCodeFromTS(originalInstanceTime / 1000L)
|
val originalDayCode = Formatter.getDayCodeFromTS(originalInstanceTime / 1000L)
|
||||||
if (parentEvent != null && !parentEvent.repetitionExceptions.contains(originalDayCode)) {
|
if (parentEvent != null) {
|
||||||
val storedEventId = context.eventsDB.getEventIdWithImportId(importId)
|
// add this event to the parent event's list of exceptions
|
||||||
if (storedEventId != null) {
|
if (!parentEvent.repetitionExceptions.contains(originalDayCode)) {
|
||||||
event.id = storedEventId
|
parentEvent.addRepetitionException(originalDayCode)
|
||||||
|
eventsHelper.insertEvent(parentEvent, addToCalDAV = false, showToasts = false)
|
||||||
|
}
|
||||||
|
|
||||||
|
// store the event in the local db only if it is an occurrence that has been modified and not deleted
|
||||||
|
if (status != Events.STATUS_CANCELED && title.isNotEmpty()) {
|
||||||
|
val storedEventId = context.eventsDB.getEventIdWithImportId(importId)
|
||||||
|
if (storedEventId != null) {
|
||||||
|
event.id = storedEventId
|
||||||
|
}
|
||||||
|
event.parentId = parentEvent.id!!
|
||||||
|
eventsHelper.insertEvent(event, addToCalDAV = false, showToasts = false)
|
||||||
|
} else {
|
||||||
|
// delete the deleted exception event from local db
|
||||||
|
val storedEventId = context.eventsDB.getEventIdWithImportId(importId)
|
||||||
|
if (storedEventId != null) {
|
||||||
|
eventsHelper.deleteEvent(storedEventId, true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
event.parentId = parentEvent.id!!
|
|
||||||
parentEvent.addRepetitionException(originalDayCode)
|
|
||||||
eventsHelper.insertEvent(parentEvent, addToCalDAV = false, showToasts = false)
|
|
||||||
|
|
||||||
return@queryCursorInlined
|
return@queryCursorInlined
|
||||||
}
|
}
|
||||||
@@ -432,6 +448,25 @@ class CalDAVHelper(val context: Context) {
|
|||||||
put(Events.ALL_DAY, 0)
|
put(Events.ALL_DAY, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val parentEventId = event.parentId
|
||||||
|
if (parentEventId != 0L) {
|
||||||
|
val parentEvent = context.eventsDB.getEventWithId(parentEventId) ?: return@apply
|
||||||
|
val isParentAllDay = parentEvent.getIsAllDay()
|
||||||
|
// original instance time must be in UTC when the parent is an all-day event
|
||||||
|
val originalInstanceTS = if (isParentAllDay && !event.getIsAllDay()) {
|
||||||
|
Formatter.getShiftedUtcTS(event.startTS)
|
||||||
|
} else {
|
||||||
|
event.startTS
|
||||||
|
}
|
||||||
|
put(Events.ORIGINAL_ID, parentEvent.getCalDAVEventId())
|
||||||
|
put(Events.ORIGINAL_INSTANCE_TIME, originalInstanceTS * 1000L)
|
||||||
|
if (isParentAllDay) {
|
||||||
|
put(Events.ORIGINAL_ALL_DAY, 1)
|
||||||
|
} else {
|
||||||
|
put(Events.ORIGINAL_ALL_DAY, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
put(Events.DTSTART, event.startTS * 1000L)
|
put(Events.DTSTART, event.startTS * 1000L)
|
||||||
put(Events.EVENT_TIMEZONE, event.getTimeZoneString())
|
put(Events.EVENT_TIMEZONE, event.getTimeZoneString())
|
||||||
if (event.repeatInterval > 0) {
|
if (event.repeatInterval > 0) {
|
||||||
|
@@ -116,6 +116,7 @@ class EventsHelper(val context: Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
maybeUpdateParentExceptions(event)
|
||||||
event.id = eventsDB.insertOrUpdate(event)
|
event.id = eventsDB.insertOrUpdate(event)
|
||||||
|
|
||||||
context.updateWidgets()
|
context.updateWidgets()
|
||||||
@@ -129,12 +130,24 @@ class EventsHelper(val context: Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun insertTask(task: Event, showToasts: Boolean, callback: () -> Unit) {
|
fun insertTask(task: Event, showToasts: Boolean, callback: () -> Unit) {
|
||||||
|
maybeUpdateParentExceptions(task)
|
||||||
task.id = eventsDB.insertOrUpdate(task)
|
task.id = eventsDB.insertOrUpdate(task)
|
||||||
context.updateWidgets()
|
context.updateWidgets()
|
||||||
context.scheduleNextEventReminder(task, showToasts)
|
context.scheduleNextEventReminder(task, showToasts)
|
||||||
callback()
|
callback()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun maybeUpdateParentExceptions(event: Event) {
|
||||||
|
// if the event is an exception from another event, update the parent event's exceptions list
|
||||||
|
val parentEventId = event.parentId
|
||||||
|
if (parentEventId != 0L) {
|
||||||
|
val parentEvent = eventsDB.getEventOrTaskWithId(parentEventId) ?: return
|
||||||
|
val startDayCode = Formatter.getDayCodeFromTS(event.startTS)
|
||||||
|
parentEvent.addRepetitionException(startDayCode)
|
||||||
|
eventsDB.updateEventRepetitionExceptions(parentEvent.repetitionExceptions.toString(), parentEventId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun insertEvents(events: ArrayList<Event>, addToCalDAV: Boolean) {
|
fun insertEvents(events: ArrayList<Event>, addToCalDAV: Boolean) {
|
||||||
try {
|
try {
|
||||||
for (event in events) {
|
for (event in events) {
|
||||||
@@ -232,14 +245,12 @@ class EventsHelper(val context: Context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addEventRepetitionException(parentEventId: Long, occurrenceTS: Long, addToCalDAV: Boolean) {
|
fun deleteRepeatingEventOccurrence(parentEventId: Long, occurrenceTS: Long, addToCalDAV: Boolean) {
|
||||||
ensureBackgroundThread {
|
ensureBackgroundThread {
|
||||||
val parentEvent = eventsDB.getEventOrTaskWithId(parentEventId) ?: return@ensureBackgroundThread
|
val parentEvent = eventsDB.getEventOrTaskWithId(parentEventId) ?: return@ensureBackgroundThread
|
||||||
var repetitionExceptions = parentEvent.repetitionExceptions
|
val occurrenceDayCode = Formatter.getDayCodeFromTS(occurrenceTS)
|
||||||
repetitionExceptions.add(Formatter.getDayCodeFromTS(occurrenceTS))
|
parentEvent.addRepetitionException(occurrenceDayCode)
|
||||||
repetitionExceptions = repetitionExceptions.distinct().toMutableList() as ArrayList<String>
|
eventsDB.updateEventRepetitionExceptions(parentEvent.repetitionExceptions.toString(), parentEventId)
|
||||||
|
|
||||||
eventsDB.updateEventRepetitionExceptions(repetitionExceptions.toString(), parentEventId)
|
|
||||||
context.scheduleNextEventReminder(parentEvent, false)
|
context.scheduleNextEventReminder(parentEvent, false)
|
||||||
|
|
||||||
if (addToCalDAV && config.caldavSync) {
|
if (addToCalDAV && config.caldavSync) {
|
||||||
|
@@ -103,7 +103,7 @@ interface EventsDao {
|
|||||||
@Query("SELECT id FROM events WHERE event_type IN (:eventTypeIds) AND type = $TYPE_EVENT")
|
@Query("SELECT id FROM events WHERE event_type IN (:eventTypeIds) AND type = $TYPE_EVENT")
|
||||||
fun getEventIdsByEventType(eventTypeIds: List<Long>): List<Long>
|
fun getEventIdsByEventType(eventTypeIds: List<Long>): List<Long>
|
||||||
|
|
||||||
@Query("SELECT id FROM events WHERE parent_id IN (:parentIds) AND type = $TYPE_EVENT")
|
@Query("SELECT id FROM events WHERE parent_id IN (:parentIds)")
|
||||||
fun getEventIdsWithParentIds(parentIds: List<Long>): List<Long>
|
fun getEventIdsWithParentIds(parentIds: List<Long>): List<Long>
|
||||||
|
|
||||||
@Query("SELECT id FROM events WHERE source = :source AND import_id != \"\" AND type = $TYPE_EVENT")
|
@Query("SELECT id FROM events WHERE source = :source AND import_id != \"\" AND type = $TYPE_EVENT")
|
||||||
|
Reference in New Issue
Block a user