mirror of
https://github.com/etesync/android
synced 2024-11-22 07:58:09 +00:00
snap
This commit is contained in:
parent
7209d634a5
commit
88dad0a538
@ -199,7 +199,7 @@ class LocalAddressBook(
|
|||||||
accountManager.removeAccount(account, null, null)
|
accountManager.removeAccount(account, null, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun findAll(): List<LocalAddress> = queryContacts(RawContacts.DELETED + "== 0", null)
|
override fun findAll(): List<LocalAddress> = queryContacts(RawContacts.DELETED + "== 0", null)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an array of local contacts/groups which have been deleted locally. (DELETED != 0).
|
* Returns an array of local contacts/groups which have been deleted locally. (DELETED != 0).
|
||||||
|
@ -13,82 +13,114 @@ import android.content.ContentProviderClient
|
|||||||
import android.content.ContentProviderOperation
|
import android.content.ContentProviderOperation
|
||||||
import android.content.ContentUris
|
import android.content.ContentUris
|
||||||
import android.content.ContentValues
|
import android.content.ContentValues
|
||||||
import android.database.Cursor
|
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.RemoteException
|
import android.os.RemoteException
|
||||||
import android.provider.CalendarContract
|
import android.provider.CalendarContract
|
||||||
import android.provider.CalendarContract.Calendars
|
import android.provider.CalendarContract.*
|
||||||
import android.provider.CalendarContract.Events
|
import at.bitfire.ical4android.*
|
||||||
import android.provider.CalendarContract.Reminders
|
|
||||||
import android.text.TextUtils
|
|
||||||
|
|
||||||
import com.etesync.syncadapter.App
|
import com.etesync.syncadapter.App
|
||||||
import com.etesync.syncadapter.model.CollectionInfo
|
|
||||||
import com.etesync.syncadapter.model.JournalEntity
|
import com.etesync.syncadapter.model.JournalEntity
|
||||||
|
|
||||||
import net.fortuna.ical4j.model.component.VTimeZone
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils
|
import org.apache.commons.lang3.StringUtils
|
||||||
|
|
||||||
import java.io.FileNotFoundException
|
import java.io.FileNotFoundException
|
||||||
import java.util.LinkedList
|
import java.util.*
|
||||||
|
import java.util.logging.Level
|
||||||
|
|
||||||
import at.bitfire.ical4android.AndroidCalendar
|
class LocalCalendar private constructor(
|
||||||
import at.bitfire.ical4android.AndroidCalendarFactory
|
account: Account,
|
||||||
import at.bitfire.ical4android.BatchOperation
|
provider: ContentProviderClient,
|
||||||
import at.bitfire.ical4android.CalendarStorageException
|
id: Long
|
||||||
import at.bitfire.ical4android.DateUtils
|
): AndroidCalendar<LocalEvent>(account, provider, LocalEvent.Factory, id), LocalCollection<LocalEvent> {
|
||||||
|
|
||||||
class LocalCalendar protected constructor(account: Account, provider: ContentProviderClient, id: Long) : AndroidCalendar(account, provider, LocalEvent.Factory.INSTANCE, id), LocalCollection<LocalEvent> {
|
companion object {
|
||||||
|
val defaultColor = -0x743cb6 // light green 500
|
||||||
|
|
||||||
override val deleted: Array<LocalEvent>
|
val COLUMN_CTAG = Calendars.CAL_SYNC1
|
||||||
@Throws(CalendarStorageException::class)
|
|
||||||
get() = queryEvents(Events.DELETED + "!=0 AND " + Events.ORIGINAL_ID + " IS NULL", null) as Array<LocalEvent>
|
|
||||||
|
|
||||||
override val withoutFileName: Array<LocalEvent>
|
fun create(account: Account, provider: ContentProviderClient, journalEntity: JournalEntity): Uri {
|
||||||
@Throws(CalendarStorageException::class)
|
val values = valuesFromCollectionInfo(journalEntity, true)
|
||||||
get() = queryEvents(Events._SYNC_ID + " IS NULL AND " + Events.ORIGINAL_ID + " IS NULL", null) as Array<LocalEvent>
|
|
||||||
|
|
||||||
|
// ACCOUNT_NAME and ACCOUNT_TYPE are required (see docs)! If it's missing, other apps will crash.
|
||||||
|
values.put(Calendars.ACCOUNT_NAME, account.name)
|
||||||
|
values.put(Calendars.ACCOUNT_TYPE, account.type)
|
||||||
|
values.put(Calendars.OWNER_ACCOUNT, account.name)
|
||||||
|
|
||||||
val all: Array<LocalEvent>
|
// flag as visible & synchronizable at creation, might be changed by user at any time
|
||||||
@Throws(CalendarStorageException::class)
|
values.put(Calendars.VISIBLE, 1)
|
||||||
get() = queryEvents(null, null) as Array<LocalEvent>
|
values.put(Calendars.SYNC_EVENTS, 1)
|
||||||
|
|
||||||
override// get dirty events which are required to have an increased SEQUENCE value
|
return AndroidCalendar.create(account, provider, values)
|
||||||
// sequence has not been assigned yet (i.e. this event was just locally created)
|
|
||||||
val dirty: Array<LocalEvent>
|
|
||||||
@Throws(CalendarStorageException::class, FileNotFoundException::class)
|
|
||||||
get() {
|
|
||||||
val dirty = LinkedList<LocalEvent>()
|
|
||||||
for (event in queryEvents(Events.DIRTY + "!=0 AND " + Events.DELETED + "==0 AND " + Events.ORIGINAL_ID + " IS NULL", null) as Array<LocalEvent>) {
|
|
||||||
if (event.event.sequence == null)
|
|
||||||
event.event.sequence = 0
|
|
||||||
else if (event.weAreOrganizer)
|
|
||||||
event.event.sequence++
|
|
||||||
dirty.add(event)
|
|
||||||
}
|
|
||||||
|
|
||||||
return dirty.toTypedArray()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun eventBaseInfoColumns(): Array<String> {
|
fun findByName(account: Account, provider: ContentProviderClient, factory: Factory, name: String): LocalCalendar?
|
||||||
return BASE_INFO_COLUMNS
|
= AndroidCalendar.find(account, provider, factory, Calendars.NAME + "==?", arrayOf(name)).firstOrNull()
|
||||||
|
|
||||||
|
private fun valuesFromCollectionInfo(journalEntity: JournalEntity, withColor: Boolean): ContentValues {
|
||||||
|
val info = journalEntity.info
|
||||||
|
val values = ContentValues()
|
||||||
|
values.put(Calendars.NAME, info.uid)
|
||||||
|
values.put(Calendars.CALENDAR_DISPLAY_NAME, info.displayName)
|
||||||
|
|
||||||
|
if (withColor)
|
||||||
|
values.put(Calendars.CALENDAR_COLOR, if (info.color != null) info.color else defaultColor)
|
||||||
|
|
||||||
|
if (journalEntity.isReadOnly)
|
||||||
|
values.put(Calendars.CALENDAR_ACCESS_LEVEL, Calendars.CAL_ACCESS_READ)
|
||||||
|
else {
|
||||||
|
values.put(Calendars.CALENDAR_ACCESS_LEVEL, Calendars.CAL_ACCESS_OWNER)
|
||||||
|
values.put(Calendars.CAN_MODIFY_TIME_ZONE, 1)
|
||||||
|
values.put(Calendars.CAN_ORGANIZER_RESPOND, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
info.timeZone?.let { tzData ->
|
||||||
|
try {
|
||||||
|
val timeZone = DateUtils.parseVTimeZone(tzData)
|
||||||
|
timeZone.timeZoneId?.let { tzId ->
|
||||||
|
values.put(Calendars.CALENDAR_TIME_ZONE, DateUtils.findAndroidTimezoneID(tzId.value))
|
||||||
|
}
|
||||||
|
} catch(e: IllegalArgumentException) {
|
||||||
|
App.log.log(Level.WARNING, "Couldn't parse calendar default time zone", e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
values.put(Calendars.ALLOWED_REMINDERS, Reminders.METHOD_ALERT)
|
||||||
|
values.put(Calendars.ALLOWED_AVAILABILITY, StringUtils.join(intArrayOf(Reminders.AVAILABILITY_TENTATIVE, Reminders.AVAILABILITY_FREE, Reminders.AVAILABILITY_BUSY), ","))
|
||||||
|
values.put(Calendars.ALLOWED_ATTENDEE_TYPES, StringUtils.join(intArrayOf(CalendarContract.Attendees.TYPE_OPTIONAL, CalendarContract.Attendees.TYPE_REQUIRED, CalendarContract.Attendees.TYPE_RESOURCE), ", "))
|
||||||
|
return values
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws(CalendarStorageException::class)
|
fun update(journalEntity: JournalEntity, updateColor: Boolean) =
|
||||||
fun update(journalEntity: JournalEntity, updateColor: Boolean) {
|
update(valuesFromCollectionInfo(journalEntity, updateColor))
|
||||||
update(valuesFromCollectionInfo(journalEntity, updateColor))
|
|
||||||
|
|
||||||
|
override fun findDeleted() =
|
||||||
|
queryEvents("${Events.DELETED}!=0 AND ${Events.ORIGINAL_ID} IS NULL", null)
|
||||||
|
|
||||||
|
override fun findDirty(): List<LocalEvent> {
|
||||||
|
val dirty = LinkedList<LocalEvent>()
|
||||||
|
|
||||||
|
// get dirty events which are required to have an increased SEQUENCE value
|
||||||
|
for (localEvent in queryEvents("${Events.DIRTY}!=0 AND ${Events.ORIGINAL_ID} IS NULL", null)) {
|
||||||
|
val event = localEvent.event!!
|
||||||
|
val sequence = event.sequence
|
||||||
|
if (event.sequence == null) // sequence has not been assigned yet (i.e. this event was just locally created)
|
||||||
|
event.sequence = 0
|
||||||
|
else if (localEvent.weAreOrganizer)
|
||||||
|
event.sequence = sequence!! + 1
|
||||||
|
dirty += localEvent
|
||||||
|
}
|
||||||
|
|
||||||
|
return dirty
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws(CalendarStorageException::class)
|
override fun findWithoutFileName(): List<LocalEvent>
|
||||||
override fun findByUid(uid: String): LocalEvent? {
|
= queryEvents(Events._SYNC_ID + " IS NULL AND " + Events.ORIGINAL_ID + " IS NULL", null)
|
||||||
val ret = queryEvents(Events._SYNC_ID + " =? ", arrayOf(uid)) as Array<LocalEvent>
|
|
||||||
return if (ret != null && ret.size > 0) {
|
override fun findAll(): List<LocalEvent>
|
||||||
ret[0]
|
= queryEvents(null, null)
|
||||||
} else null
|
|
||||||
}
|
override fun findByUid(uid: String): LocalEvent?
|
||||||
|
= queryEvents(Events._SYNC_ID + " =? ", arrayOf(uid)).firstOrNull()
|
||||||
|
|
||||||
@Throws(CalendarStorageException::class)
|
|
||||||
fun processDirtyExceptions() {
|
fun processDirtyExceptions() {
|
||||||
// process deleted exceptions
|
// process deleted exceptions
|
||||||
App.log.info("Processing deleted exceptions")
|
App.log.info("Processing deleted exceptions")
|
||||||
@ -163,19 +195,15 @@ class LocalCalendar protected constructor(account: Account, provider: ContentPro
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws(CalendarStorageException::class)
|
|
||||||
override fun count(): Long {
|
override fun count(): Long {
|
||||||
val where = Events.CALENDAR_ID + "=?"
|
|
||||||
val whereArgs = arrayOf(id.toString())
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
val cursor = provider.query(
|
val cursor = provider.query(
|
||||||
syncAdapterURI(Events.CONTENT_URI), null,
|
syncAdapterURI(Events.CONTENT_URI), null,
|
||||||
where, whereArgs, null)
|
Events.CALENDAR_ID + "=?", arrayOf(id.toString()), null)
|
||||||
try {
|
try {
|
||||||
return cursor.count.toLong()
|
return cursor?.count.toLong()
|
||||||
} finally {
|
} finally {
|
||||||
cursor.close()
|
cursor?.close()
|
||||||
}
|
}
|
||||||
} catch (e: RemoteException) {
|
} catch (e: RemoteException) {
|
||||||
throw CalendarStorageException("Couldn't query calendar events", e)
|
throw CalendarStorageException("Couldn't query calendar events", e)
|
||||||
@ -183,20 +211,6 @@ class LocalCalendar protected constructor(account: Account, provider: ContentPro
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class Factory : AndroidCalendarFactory {
|
|
||||||
|
|
||||||
override fun newInstance(account: Account, provider: ContentProviderClient, id: Long): AndroidCalendar {
|
|
||||||
return LocalCalendar(account, provider, id)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun newArray(size: Int): Array<AndroidCalendar?> {
|
|
||||||
return arrayOfNulls<LocalCalendar>(size) as Array<AndroidCalendar?>
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
val INSTANCE = Factory()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Fix all of the etags of all of the non-dirty events to be non-null.
|
/** Fix all of the etags of all of the non-dirty events to be non-null.
|
||||||
* Currently set to all ones.. */
|
* Currently set to all ones.. */
|
||||||
@ -218,67 +232,9 @@ class LocalCalendar protected constructor(account: Account, provider: ContentPro
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
object Factory: AndroidCalendarFactory<LocalCalendar> {
|
||||||
|
|
||||||
val defaultColor = -0x743cb6 // light green 500
|
override fun newInstance(account: Account, provider: ContentProviderClient, id: Long) =
|
||||||
|
LocalCalendar(account, provider, id)
|
||||||
val COLUMN_CTAG = Calendars.CAL_SYNC1
|
|
||||||
|
|
||||||
internal var BASE_INFO_COLUMNS = arrayOf(Events._ID, Events._SYNC_ID, LocalEvent.COLUMN_ETAG)
|
|
||||||
|
|
||||||
@Throws(CalendarStorageException::class)
|
|
||||||
fun create(account: Account, provider: ContentProviderClient, journalEntity: JournalEntity): Uri {
|
|
||||||
val values = valuesFromCollectionInfo(journalEntity, true)
|
|
||||||
|
|
||||||
// ACCOUNT_NAME and ACCOUNT_TYPE are required (see docs)! If it's missing, other apps will crash.
|
|
||||||
values.put(Calendars.ACCOUNT_NAME, account.name)
|
|
||||||
values.put(Calendars.ACCOUNT_TYPE, account.type)
|
|
||||||
values.put(Calendars.OWNER_ACCOUNT, account.name)
|
|
||||||
|
|
||||||
// flag as visible & synchronizable at creation, might be changed by user at any time
|
|
||||||
values.put(Calendars.VISIBLE, 1)
|
|
||||||
values.put(Calendars.SYNC_EVENTS, 1)
|
|
||||||
|
|
||||||
return AndroidCalendar.create(account, provider, values)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Throws(FileNotFoundException::class, CalendarStorageException::class)
|
|
||||||
fun findByName(account: Account, provider: ContentProviderClient, factory: AndroidCalendarFactory, name: String): LocalCalendar? {
|
|
||||||
val ret = LocalCalendar.find(account, provider, factory, Calendars.NAME + "==?", arrayOf(name))
|
|
||||||
if (ret.size == 1) {
|
|
||||||
return ret[0]
|
|
||||||
} else {
|
|
||||||
App.log.severe("No calendar found for name $name")
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun valuesFromCollectionInfo(journalEntity: JournalEntity, withColor: Boolean): ContentValues {
|
|
||||||
val info = journalEntity.info
|
|
||||||
val values = ContentValues()
|
|
||||||
values.put(Calendars.NAME, info.uid)
|
|
||||||
values.put(Calendars.CALENDAR_DISPLAY_NAME, info.displayName)
|
|
||||||
|
|
||||||
if (withColor)
|
|
||||||
values.put(Calendars.CALENDAR_COLOR, if (info.color != null) info.color else defaultColor)
|
|
||||||
|
|
||||||
if (journalEntity.isReadOnly)
|
|
||||||
values.put(Calendars.CALENDAR_ACCESS_LEVEL, Calendars.CAL_ACCESS_READ)
|
|
||||||
else {
|
|
||||||
values.put(Calendars.CALENDAR_ACCESS_LEVEL, Calendars.CAL_ACCESS_OWNER)
|
|
||||||
values.put(Calendars.CAN_MODIFY_TIME_ZONE, 1)
|
|
||||||
values.put(Calendars.CAN_ORGANIZER_RESPOND, 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!TextUtils.isEmpty(info.timeZone)) {
|
|
||||||
val timeZone = DateUtils.parseVTimeZone(info.timeZone)
|
|
||||||
if (timeZone != null && timeZone.timeZoneId != null)
|
|
||||||
values.put(Calendars.CALENDAR_TIME_ZONE, DateUtils.findAndroidTimezoneID(timeZone.timeZoneId.value))
|
|
||||||
}
|
|
||||||
values.put(Calendars.ALLOWED_REMINDERS, Reminders.METHOD_ALERT)
|
|
||||||
values.put(Calendars.ALLOWED_AVAILABILITY, StringUtils.join(intArrayOf(Reminders.AVAILABILITY_TENTATIVE, Reminders.AVAILABILITY_FREE, Reminders.AVAILABILITY_BUSY), ","))
|
|
||||||
values.put(Calendars.ALLOWED_ATTENDEE_TYPES, StringUtils.join(intArrayOf(CalendarContract.Attendees.TYPE_OPTIONAL, CalendarContract.Attendees.TYPE_REQUIRED, CalendarContract.Attendees.TYPE_RESOURCE), ", "))
|
|
||||||
return values
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ interface LocalCollection<out T: LocalResource<*>> {
|
|||||||
fun findDeleted(): List<T>
|
fun findDeleted(): List<T>
|
||||||
fun findDirty(): List<T>
|
fun findDirty(): List<T>
|
||||||
fun findWithoutFileName(): List<T>
|
fun findWithoutFileName(): List<T>
|
||||||
|
fun findAll(): List<T>
|
||||||
|
|
||||||
fun findByUid(uid: String): T?
|
fun findByUid(uid: String): T?
|
||||||
|
|
||||||
|
@ -9,82 +9,92 @@
|
|||||||
package com.etesync.syncadapter.resource
|
package com.etesync.syncadapter.resource
|
||||||
|
|
||||||
import android.accounts.Account
|
import android.accounts.Account
|
||||||
import android.content.ContentProviderClient
|
|
||||||
import android.content.ContentResolver
|
|
||||||
import android.content.ContentValues
|
import android.content.ContentValues
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.database.Cursor
|
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.RemoteException
|
import android.os.RemoteException
|
||||||
|
|
||||||
import com.etesync.syncadapter.model.CollectionInfo
|
|
||||||
|
|
||||||
import org.dmfs.provider.tasks.TaskContract.TaskLists
|
|
||||||
import org.dmfs.provider.tasks.TaskContract.Tasks
|
|
||||||
|
|
||||||
import java.io.FileNotFoundException
|
|
||||||
|
|
||||||
import at.bitfire.ical4android.AndroidTaskList
|
import at.bitfire.ical4android.AndroidTaskList
|
||||||
import at.bitfire.ical4android.AndroidTaskListFactory
|
import at.bitfire.ical4android.AndroidTaskListFactory
|
||||||
import at.bitfire.ical4android.CalendarStorageException
|
import at.bitfire.ical4android.CalendarStorageException
|
||||||
import at.bitfire.ical4android.TaskProvider
|
import at.bitfire.ical4android.TaskProvider
|
||||||
|
import com.etesync.syncadapter.model.JournalEntity
|
||||||
|
import org.dmfs.tasks.contract.TaskContract.TaskLists
|
||||||
|
import org.dmfs.tasks.contract.TaskContract.Tasks
|
||||||
|
|
||||||
class LocalTaskList protected constructor(account: Account, provider: TaskProvider, id: Long) : AndroidTaskList(account, provider, LocalTask.Factory.INSTANCE, id), LocalCollection<LocalTask> {
|
class LocalTaskList private constructor(
|
||||||
|
account: Account,
|
||||||
|
provider: TaskProvider,
|
||||||
|
id: Long
|
||||||
|
): AndroidTaskList<LocalTask>(account, provider, LocalTask.Factory, id), LocalCollection<LocalTask> {
|
||||||
|
companion object {
|
||||||
|
val defaultColor = -0x3c1592 // "DAVdroid green"
|
||||||
|
|
||||||
override val deleted: Array<LocalTask>
|
fun tasksProviderAvailable(context: Context): Boolean {
|
||||||
@Throws(CalendarStorageException::class)
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
|
||||||
get() = queryTasks(Tasks._DELETED + "!=0", null) as Array<LocalTask>
|
return context.packageManager.resolveContentProvider(TaskProvider.ProviderName.OpenTasks.authority, 0) != null
|
||||||
|
else {
|
||||||
override val withoutFileName: Array<LocalTask>
|
val provider = TaskProvider.acquire(context, TaskProvider.ProviderName.OpenTasks)
|
||||||
@Throws(CalendarStorageException::class)
|
provider?.use { return true }
|
||||||
get() = queryTasks(Tasks._SYNC_ID + " IS NULL", null) as Array<LocalTask>
|
return false
|
||||||
|
|
||||||
override// sequence has not been assigned yet (i.e. this task was just locally created)
|
|
||||||
val dirty: Array<LocalTask>
|
|
||||||
@Throws(CalendarStorageException::class, FileNotFoundException::class)
|
|
||||||
get() {
|
|
||||||
val tasks = queryTasks(Tasks._DIRTY + "!=0 AND " + Tasks._DELETED + "== 0", null) as Array<LocalTask>
|
|
||||||
for (task in tasks) {
|
|
||||||
if (task.task.sequence == null)
|
|
||||||
task.task.sequence = 0
|
|
||||||
else
|
|
||||||
task.task.sequence++
|
|
||||||
}
|
}
|
||||||
return tasks
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun create(account: Account, provider: TaskProvider, journalEntity: JournalEntity): Uri {
|
||||||
|
val values = valuesFromCollectionInfo(journalEntity, true)
|
||||||
|
values.put(TaskLists.OWNER, account.name)
|
||||||
|
values.put(TaskLists.SYNC_ENABLED, 1)
|
||||||
|
values.put(TaskLists.VISIBLE, 1)
|
||||||
|
return create(account, provider, values)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun valuesFromCollectionInfo(journalEntity: JournalEntity, withColor: Boolean): ContentValues {
|
||||||
|
val info = journalEntity.info
|
||||||
|
val values = ContentValues(3)
|
||||||
|
values.put(TaskLists._SYNC_ID, info.uid)
|
||||||
|
values.put(TaskLists.LIST_NAME, if (info.displayName.isNullOrBlank()) info.uid else info.displayName)
|
||||||
|
|
||||||
|
if (withColor)
|
||||||
|
values.put(TaskLists.LIST_COLOR, info.color ?: defaultColor)
|
||||||
|
|
||||||
|
return values
|
||||||
|
}
|
||||||
|
|
||||||
override fun taskBaseInfoColumns(): Array<String> {
|
|
||||||
return BASE_INFO_COLUMNS
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws(CalendarStorageException::class)
|
fun update(journalEntity: JournalEntity, updateColor: Boolean) =
|
||||||
fun update(info: CollectionInfo, updateColor: Boolean) {
|
update(valuesFromCollectionInfo(journalEntity, updateColor))
|
||||||
update(valuesFromCollectionInfo(info, updateColor))
|
|
||||||
|
override fun findDeleted() = queryTasks("${Tasks._DELETED}!=0", null)
|
||||||
|
|
||||||
|
override fun findDirty(): List<LocalTask> {
|
||||||
|
val tasks = queryTasks("${Tasks._DIRTY}!=0", null)
|
||||||
|
for (localTask in tasks) {
|
||||||
|
val task = requireNotNull(localTask.task)
|
||||||
|
val sequence = task.sequence
|
||||||
|
if (sequence == null) // sequence has not been assigned yet (i.e. this task was just locally created)
|
||||||
|
task.sequence = 0
|
||||||
|
else
|
||||||
|
task.sequence = sequence + 1
|
||||||
|
}
|
||||||
|
return tasks
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws(CalendarStorageException::class)
|
override fun findWithoutFileName(): List<LocalTask>
|
||||||
override fun findByUid(uid: String): LocalTask? {
|
= queryTasks(Tasks._SYNC_ID + " IS NULL", null)
|
||||||
val ret = queryTasks(Tasks._SYNC_ID + " =? ", arrayOf(uid)) as Array<LocalTask>
|
|
||||||
return if (ret != null && ret.size > 0) {
|
override fun findByUid(uid: String): LocalTask?
|
||||||
ret[0]
|
= queryTasks(Tasks._SYNC_ID + " =? ", arrayOf(uid)).firstOrNull()
|
||||||
} else null
|
|
||||||
}
|
|
||||||
|
|
||||||
@Throws(CalendarStorageException::class)
|
|
||||||
override fun count(): Long {
|
override fun count(): Long {
|
||||||
val where = Tasks.LIST_ID + "=?"
|
|
||||||
val whereArgs = arrayOf(id.toString())
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
val cursor = provider.client.query(
|
val cursor = provider.client.query(
|
||||||
syncAdapterURI(provider.tasksUri()), null,
|
TaskProvider.syncAdapterUri(provider.tasksUri()), null,
|
||||||
where, whereArgs, null)
|
Tasks.LIST_ID + "=?", arrayOf(id.toString()), null)
|
||||||
try {
|
try {
|
||||||
return cursor.count.toLong()
|
return cursor?.count.toLong()
|
||||||
} finally {
|
} finally {
|
||||||
cursor.close()
|
cursor?.close()
|
||||||
}
|
}
|
||||||
} catch (e: RemoteException) {
|
} catch (e: RemoteException) {
|
||||||
throw CalendarStorageException("Couldn't query calendar events", e)
|
throw CalendarStorageException("Couldn't query calendar events", e)
|
||||||
@ -92,78 +102,10 @@ class LocalTaskList protected constructor(account: Account, provider: TaskProvid
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object Factory: AndroidTaskListFactory<LocalTaskList> {
|
||||||
|
|
||||||
class Factory : AndroidTaskListFactory {
|
override fun newInstance(account: Account, provider: TaskProvider, id: Long) =
|
||||||
|
LocalTaskList(account, provider, id)
|
||||||
|
|
||||||
override fun newInstance(account: Account, provider: TaskProvider, id: Long): AndroidTaskList {
|
|
||||||
return LocalTaskList(account, provider, id)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun newArray(size: Int): Array<AndroidTaskList?> {
|
|
||||||
return arrayOfNulls<LocalTaskList>(size) as Array<AndroidTaskList?>
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
val INSTANCE = Factory()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
|
||||||
|
|
||||||
val defaultColor = -0x3c1592 // "DAVdroid green"
|
|
||||||
|
|
||||||
val COLUMN_CTAG = TaskLists.SYNC_VERSION
|
|
||||||
|
|
||||||
internal var BASE_INFO_COLUMNS = arrayOf(Tasks._ID, Tasks._SYNC_ID, LocalTask.COLUMN_ETAG)
|
|
||||||
|
|
||||||
@Throws(CalendarStorageException::class)
|
|
||||||
fun create(account: Account, provider: TaskProvider, info: CollectionInfo): Uri {
|
|
||||||
val values = valuesFromCollectionInfo(info, true)
|
|
||||||
values.put(TaskLists.OWNER, account.name)
|
|
||||||
values.put(TaskLists.SYNC_ENABLED, 1)
|
|
||||||
values.put(TaskLists.VISIBLE, 1)
|
|
||||||
return AndroidTaskList.create(account, provider, values)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun valuesFromCollectionInfo(info: CollectionInfo, withColor: Boolean): ContentValues {
|
|
||||||
val values = ContentValues()
|
|
||||||
values.put(TaskLists._SYNC_ID, info.uid)
|
|
||||||
values.put(TaskLists.LIST_NAME, info.displayName)
|
|
||||||
|
|
||||||
if (withColor)
|
|
||||||
values.put(TaskLists.LIST_COLOR, if (info.color != null) info.color else defaultColor)
|
|
||||||
|
|
||||||
return values
|
|
||||||
}
|
|
||||||
|
|
||||||
// helpers
|
|
||||||
|
|
||||||
fun tasksProviderAvailable(context: Context): Boolean {
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
|
|
||||||
return context.packageManager.resolveContentProvider(TaskProvider.ProviderName.OpenTasks.authority, 0) != null
|
|
||||||
else {
|
|
||||||
val provider = TaskProvider.acquire(context.contentResolver, TaskProvider.ProviderName.OpenTasks)
|
|
||||||
try {
|
|
||||||
return provider != null
|
|
||||||
} finally {
|
|
||||||
provider?.close()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// HELPERS
|
|
||||||
|
|
||||||
@Throws(RemoteException::class)
|
|
||||||
fun onRenameAccount(resolver: ContentResolver, oldName: String, newName: String) {
|
|
||||||
val client = resolver.acquireContentProviderClient(TaskProvider.ProviderName.OpenTasks.authority)
|
|
||||||
if (client != null) {
|
|
||||||
val values = ContentValues(1)
|
|
||||||
values.put(Tasks.ACCOUNT_NAME, newName)
|
|
||||||
client.update(Tasks.getContentUri(TaskProvider.ProviderName.OpenTasks.authority), values, Tasks.ACCOUNT_NAME + "=?", arrayOf(oldName))
|
|
||||||
client.release()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user