Loading app/build.gradle +2 −0 Original line number Diff line number Diff line Loading @@ -91,6 +91,8 @@ dependencies { implementation 'androidx.lifecycle:lifecycle-livedata:2.0.0' implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.0.0' implementation 'androidx.preference:preference:1.0.0' implementation 'androidx.constraintlayout:constraintlayout:1.1.3' implementation 'com.google.android:flexbox:1.1.0' implementation 'com.google.android.material:material:1.0.0' implementation(':dav4jvm') { Loading app/src/main/java/at/bitfire/davdroid/model/CollectionInfo.kt +3 −0 Original line number Diff line number Diff line Loading @@ -46,6 +46,7 @@ data class CollectionInfo( var timeZone: String? = null, var supportsVEVENT: Boolean = false, var supportsVTODO: Boolean = false, var supportsVJOURNAL: Boolean = false, var selected: Boolean = false, // subscriptions Loading Loading @@ -195,6 +196,7 @@ data class CollectionInfo( dest.writeString(timeZone) dest.writeByte(if (supportsVEVENT) 1 else 0) dest.writeByte(if (supportsVTODO) 1 else 0) dest.writeByte(if (supportsVJOURNAL) 1 else 0) dest.writeByte(if (selected) 1 else 0) dest.writeString(source) Loading Loading @@ -241,6 +243,7 @@ data class CollectionInfo( parcel.readByte() != 0.toByte(), parcel.readByte() != 0.toByte(), parcel.readByte() != 0.toByte(), parcel.readByte() != 0.toByte(), parcel.readString(), Loading app/src/main/java/at/bitfire/davdroid/ui/CreateCalendarActivity.kt +187 −78 Original line number Diff line number Diff line Loading @@ -9,19 +9,30 @@ package at.bitfire.davdroid.ui import android.accounts.Account import android.app.Application import android.content.Context import android.content.Intent import android.graphics.drawable.ColorDrawable import android.os.Bundle import android.text.TextUtils import android.view.Menu import android.view.MenuItem import android.view.View import android.view.ViewGroup import android.widget.ArrayAdapter import android.widget.Filter import android.widget.SpinnerAdapter import android.widget.TextView import androidx.appcompat.app.AppCompatActivity import androidx.core.app.NavUtils import androidx.loader.app.LoaderManager import androidx.loader.content.AsyncTaskLoader import androidx.loader.content.Loader import androidx.databinding.DataBindingUtil import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.MutableLiveData import androidx.lifecycle.Observer import androidx.lifecycle.ViewModelProviders import at.bitfire.davdroid.Constants import at.bitfire.davdroid.R import at.bitfire.davdroid.databinding.ActivityCreateCalendarBinding import at.bitfire.davdroid.model.CollectionInfo import at.bitfire.davdroid.model.ServiceDB import at.bitfire.ical4android.DateUtils Loading @@ -32,35 +43,46 @@ import net.fortuna.ical4j.model.Calendar import okhttp3.HttpUrl import org.apache.commons.lang3.StringUtils import java.util.* import kotlin.concurrent.thread class CreateCalendarActivity: AppCompatActivity(), LoaderManager.LoaderCallbacks<CreateCalendarActivity.AccountInfo>, ColorPickerDialogListener { class CreateCalendarActivity: AppCompatActivity(), ColorPickerDialogListener { companion object { const val EXTRA_ACCOUNT = "account" } private lateinit var account: Account private lateinit var model: Model override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) supportActionBar?.setDisplayHomeAsUpEnabled(true) account = intent.extras.getParcelable(EXTRA_ACCOUNT)!! model = ViewModelProviders.of(this).get(Model::class.java) (intent?.extras?.getParcelable(EXTRA_ACCOUNT) as? Account)?.let { model.initialize(it) } model.homeSets.observe(this, Observer { if (it.isEmpty) // no known homesets, we don't know where to create the calendar finish() }) supportActionBar?.setDisplayHomeAsUpEnabled(true) val binding = DataBindingUtil.setContentView<ActivityCreateCalendarBinding>(this, R.layout.activity_create_calendar) binding.lifecycleOwner = this binding.model = model setContentView(R.layout.activity_create_calendar) color.setOnClickListener { _ -> binding.color.setOnClickListener { _ -> ColorPickerDialog.newBuilder() .setShowAlphaSlider(false) .setColor((color.background as ColorDrawable).color) .show(this) } LoaderManager.getInstance(this).initLoader(0, null, this) binding.timezone.setAdapter(model.timezones) } override fun onColorSelected(dialogId: Int, rgb: Int) { color.setBackgroundColor(rgb) model.color.value = rgb } override fun onDialogDismissed(dialogId: Int) { Loading @@ -75,105 +97,192 @@ class CreateCalendarActivity: AppCompatActivity(), LoaderManager.LoaderCallbacks override fun onOptionsItemSelected(item: MenuItem) = if (item.itemId == android.R.id.home) { val intent = Intent(this, AccountActivity::class.java) intent.putExtra(AccountActivity.EXTRA_ACCOUNT, account) intent.putExtra(AccountActivity.EXTRA_ACCOUNT, model.account) NavUtils.navigateUpTo(this, intent) true } else false fun onCreateCollection(item: MenuItem) { val homeSet = home_sets.selectedItem as String var ok = true HttpUrl.parse(homeSet)?.let { val info = CollectionInfo(it.resolve(UUID.randomUUID().toString() + "/")!!) info.displayName = display_name.text.toString() if (info.displayName.isNullOrBlank()) { display_name.error = getString(R.string.create_collection_display_name_required) val parent = model.homeSets.value?.getItem(model.idxHomeSet.value!!) as String HttpUrl.parse(parent)?.let { parentUrl -> val info = CollectionInfo(parentUrl.resolve(UUID.randomUUID().toString() + "/")!!) val displayName = model.displayName.value if (displayName.isNullOrBlank()) { model.displayNameError.value = getString(R.string.create_collection_display_name_required) ok = false } else { info.displayName = displayName model.displayNameError.value = null } info.description = StringUtils.trimToNull(description.text.toString()) info.color = (color.background as ColorDrawable).color info.description = StringUtils.trimToNull(model.description.value) info.color = model.color.value DateUtils.tzRegistry.getTimeZone(time_zone.selectedItem as String)?.let { tz -> val tzId = model.timezone.value if (tzId.isNullOrBlank()) { model.timezoneError.value = getString(R.string.create_calendar_time_zone_required) ok = false } else { DateUtils.tzRegistry.getTimeZone(tzId)?.let { tz -> val cal = Calendar() cal.components += tz.vTimeZone info.timeZone = cal.toString() } when (type.checkedRadioButtonId) { R.id.type_events -> info.supportsVEVENT = true R.id.type_tasks -> info.supportsVTODO = true R.id.type_events_and_tasks -> { info.supportsVEVENT = true info.supportsVTODO = true } model.timezoneError.value = null } if (ok) { val supportsVEVENT = model.supportVEVENT.value ?: false val supportsVTODO = model.supportVTODO.value ?: false val supportsVJOURNAL = model.supportVJOURNAL.value ?: false if (!supportsVEVENT && !supportsVTODO && !supportsVJOURNAL) { ok = false model.typeError.value = "" } else model.typeError.value = null info.type = CollectionInfo.Type.CALENDAR CreateCollectionFragment.newInstance(account, info).show(supportFragmentManager, null) info.supportsVEVENT = supportsVEVENT info.supportsVTODO = supportsVTODO info.supportsVJOURNAL = supportsVJOURNAL if (ok) CreateCollectionFragment.newInstance(model.account!!, info).show(supportFragmentManager, null) } } class HomesetAdapter( context: Context ): ArrayAdapter<String>(context, android.R.layout.simple_list_item_1, android.R.id.text1) { init { setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item) } override fun getView(position: Int, convertView: View?, parent: ViewGroup): View { val data = getItem(position)!! val v = super.getView(position, convertView, parent) v.findViewById<TextView>(android.R.id.text1).apply { setSingleLine() ellipsize = TextUtils.TruncateAt.START } return v } override fun onCreateLoader(id: Int, args: Bundle?) = AccountInfoLoader(this, account) override fun getDropDownView(position: Int, convertView: View?, parent: ViewGroup): View { val data = getItem(position)!! val v = super.getDropDownView(position, convertView, parent) v.findViewById<TextView>(android.R.id.text1).apply { ellipsize = TextUtils.TruncateAt.START } return v } override fun onLoadFinished(loader: Loader<AccountInfo>, info: AccountInfo?) { val timeZones = TimeZone.getAvailableIDs() time_zone.adapter = ArrayAdapter<String>(this, android.R.layout.simple_spinner_dropdown_item, timeZones) } // select system time zone val defaultTimeZone = TimeZone.getDefault().id for (i in 0 until timeZones.size) if (timeZones[i] == defaultTimeZone) { time_zone.setSelection(i) break class TimeZoneAdapter( context: Context ): ArrayAdapter<String>(context, android.R.layout.simple_list_item_1, android.R.id.text1) { val tz = TimeZone.getAvailableIDs() override fun getFilter(): Filter { return object: Filter() { override fun performFiltering(constraint: CharSequence?): FilterResults { val filtered = constraint?.let { tz.filter { it.contains(constraint, true) } } ?: listOf() val results = FilterResults() results.values = filtered results.count = filtered.size return results } override fun publishResults(constraint: CharSequence?, results: FilterResults) { clear() @Suppress("UNCHECKED_CAST") addAll(results.values as List<String>) if (results.count >= 0) notifyDataSetChanged() else notifyDataSetInvalidated() } } } info?.let { home_sets.adapter = ArrayAdapter<String>(this, android.R.layout.simple_spinner_dropdown_item, info.homeSets) } class Model( application: Application ): AndroidViewModel(application) { class TimeZoneInfo( val id: String, val displayName: String ) { override fun toString() = id } override fun onLoaderReset(loader: Loader<AccountInfo>) {} var account: Account? = null val displayName = MutableLiveData<String>() val displayNameError = MutableLiveData<String>() val description = MutableLiveData<String>() val color = MutableLiveData<Int>() class AccountInfo { val homeSets = LinkedList<String>() val homeSets = MutableLiveData<SpinnerAdapter>() val idxHomeSet = MutableLiveData<Int>() val timezones = TimeZoneAdapter(application) val timezone = MutableLiveData<String>() val timezoneError = MutableLiveData<String>() val typeError = MutableLiveData<String>() val supportVEVENT = MutableLiveData<Boolean>() val supportVTODO = MutableLiveData<Boolean>() val supportVJOURNAL = MutableLiveData<Boolean>() fun initialize(account: Account) { synchronized(this) { if (this.account != null) return this.account = account } class AccountInfoLoader( context: Context, val account: Account ): AsyncTaskLoader<AccountInfo>(context) { color.value = Constants.DAVDROID_GREEN_RGBA timezone.value = TimeZone.getDefault().id override fun onStartLoading() = forceLoad() supportVEVENT.value = true supportVTODO.value = true supportVJOURNAL.value = true override fun loadInBackground(): AccountInfo? { val info = AccountInfo() ServiceDB.OpenHelper(context).use { dbHelper -> thread { // load account info ServiceDB.OpenHelper(getApplication()).use { dbHelper -> val adapter = HomesetAdapter(getApplication()) val db = dbHelper.readableDatabase db.query(ServiceDB.Services._TABLE, arrayOf(ServiceDB.Services.ID), "${ServiceDB.Services.ACCOUNT_NAME}=? AND ${ServiceDB.Services.SERVICE}=?", arrayOf(account.name, ServiceDB.Services.SERVICE_CALDAV), null, null, null).use { cursor -> if (!cursor.moveToNext()) return null if (cursor.moveToNext()) { val strServiceID = cursor.getString(0) db.query(ServiceDB.HomeSets._TABLE, arrayOf(ServiceDB.HomeSets.URL), "${ServiceDB.HomeSets.SERVICE_ID}=?", arrayOf(strServiceID), null, null, null).use { c -> while (c.moveToNext()) info.homeSets += c.getString(0) adapter.add(c.getString(0)) } } } homeSets.postValue(adapter) idxHomeSet.postValue(0) } return info } } } } app/src/main/java/at/bitfire/davdroid/ui/CreateCollectionFragment.kt +5 −0 Original line number Diff line number Diff line Loading @@ -171,6 +171,11 @@ class CreateCollectionFragment: DialogFragment(), LoaderManager.LoaderCallbacks< attribute(null, "name", "VTODO") endTag(XmlUtils.NS_CALDAV, "comp") } if (info.supportsVJOURNAL) { startTag(XmlUtils.NS_CALDAV, "comp") attribute(null, "name", "VJOURNAL") endTag(XmlUtils.NS_CALDAV, "comp") } endTag(XmlUtils.NS_CALDAV, "supported-calendar-component-set") } Loading app/src/main/res/layout/activity_create_calendar.xml +122 −97 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
app/build.gradle +2 −0 Original line number Diff line number Diff line Loading @@ -91,6 +91,8 @@ dependencies { implementation 'androidx.lifecycle:lifecycle-livedata:2.0.0' implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.0.0' implementation 'androidx.preference:preference:1.0.0' implementation 'androidx.constraintlayout:constraintlayout:1.1.3' implementation 'com.google.android:flexbox:1.1.0' implementation 'com.google.android.material:material:1.0.0' implementation(':dav4jvm') { Loading
app/src/main/java/at/bitfire/davdroid/model/CollectionInfo.kt +3 −0 Original line number Diff line number Diff line Loading @@ -46,6 +46,7 @@ data class CollectionInfo( var timeZone: String? = null, var supportsVEVENT: Boolean = false, var supportsVTODO: Boolean = false, var supportsVJOURNAL: Boolean = false, var selected: Boolean = false, // subscriptions Loading Loading @@ -195,6 +196,7 @@ data class CollectionInfo( dest.writeString(timeZone) dest.writeByte(if (supportsVEVENT) 1 else 0) dest.writeByte(if (supportsVTODO) 1 else 0) dest.writeByte(if (supportsVJOURNAL) 1 else 0) dest.writeByte(if (selected) 1 else 0) dest.writeString(source) Loading Loading @@ -241,6 +243,7 @@ data class CollectionInfo( parcel.readByte() != 0.toByte(), parcel.readByte() != 0.toByte(), parcel.readByte() != 0.toByte(), parcel.readByte() != 0.toByte(), parcel.readString(), Loading
app/src/main/java/at/bitfire/davdroid/ui/CreateCalendarActivity.kt +187 −78 Original line number Diff line number Diff line Loading @@ -9,19 +9,30 @@ package at.bitfire.davdroid.ui import android.accounts.Account import android.app.Application import android.content.Context import android.content.Intent import android.graphics.drawable.ColorDrawable import android.os.Bundle import android.text.TextUtils import android.view.Menu import android.view.MenuItem import android.view.View import android.view.ViewGroup import android.widget.ArrayAdapter import android.widget.Filter import android.widget.SpinnerAdapter import android.widget.TextView import androidx.appcompat.app.AppCompatActivity import androidx.core.app.NavUtils import androidx.loader.app.LoaderManager import androidx.loader.content.AsyncTaskLoader import androidx.loader.content.Loader import androidx.databinding.DataBindingUtil import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.MutableLiveData import androidx.lifecycle.Observer import androidx.lifecycle.ViewModelProviders import at.bitfire.davdroid.Constants import at.bitfire.davdroid.R import at.bitfire.davdroid.databinding.ActivityCreateCalendarBinding import at.bitfire.davdroid.model.CollectionInfo import at.bitfire.davdroid.model.ServiceDB import at.bitfire.ical4android.DateUtils Loading @@ -32,35 +43,46 @@ import net.fortuna.ical4j.model.Calendar import okhttp3.HttpUrl import org.apache.commons.lang3.StringUtils import java.util.* import kotlin.concurrent.thread class CreateCalendarActivity: AppCompatActivity(), LoaderManager.LoaderCallbacks<CreateCalendarActivity.AccountInfo>, ColorPickerDialogListener { class CreateCalendarActivity: AppCompatActivity(), ColorPickerDialogListener { companion object { const val EXTRA_ACCOUNT = "account" } private lateinit var account: Account private lateinit var model: Model override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) supportActionBar?.setDisplayHomeAsUpEnabled(true) account = intent.extras.getParcelable(EXTRA_ACCOUNT)!! model = ViewModelProviders.of(this).get(Model::class.java) (intent?.extras?.getParcelable(EXTRA_ACCOUNT) as? Account)?.let { model.initialize(it) } model.homeSets.observe(this, Observer { if (it.isEmpty) // no known homesets, we don't know where to create the calendar finish() }) supportActionBar?.setDisplayHomeAsUpEnabled(true) val binding = DataBindingUtil.setContentView<ActivityCreateCalendarBinding>(this, R.layout.activity_create_calendar) binding.lifecycleOwner = this binding.model = model setContentView(R.layout.activity_create_calendar) color.setOnClickListener { _ -> binding.color.setOnClickListener { _ -> ColorPickerDialog.newBuilder() .setShowAlphaSlider(false) .setColor((color.background as ColorDrawable).color) .show(this) } LoaderManager.getInstance(this).initLoader(0, null, this) binding.timezone.setAdapter(model.timezones) } override fun onColorSelected(dialogId: Int, rgb: Int) { color.setBackgroundColor(rgb) model.color.value = rgb } override fun onDialogDismissed(dialogId: Int) { Loading @@ -75,105 +97,192 @@ class CreateCalendarActivity: AppCompatActivity(), LoaderManager.LoaderCallbacks override fun onOptionsItemSelected(item: MenuItem) = if (item.itemId == android.R.id.home) { val intent = Intent(this, AccountActivity::class.java) intent.putExtra(AccountActivity.EXTRA_ACCOUNT, account) intent.putExtra(AccountActivity.EXTRA_ACCOUNT, model.account) NavUtils.navigateUpTo(this, intent) true } else false fun onCreateCollection(item: MenuItem) { val homeSet = home_sets.selectedItem as String var ok = true HttpUrl.parse(homeSet)?.let { val info = CollectionInfo(it.resolve(UUID.randomUUID().toString() + "/")!!) info.displayName = display_name.text.toString() if (info.displayName.isNullOrBlank()) { display_name.error = getString(R.string.create_collection_display_name_required) val parent = model.homeSets.value?.getItem(model.idxHomeSet.value!!) as String HttpUrl.parse(parent)?.let { parentUrl -> val info = CollectionInfo(parentUrl.resolve(UUID.randomUUID().toString() + "/")!!) val displayName = model.displayName.value if (displayName.isNullOrBlank()) { model.displayNameError.value = getString(R.string.create_collection_display_name_required) ok = false } else { info.displayName = displayName model.displayNameError.value = null } info.description = StringUtils.trimToNull(description.text.toString()) info.color = (color.background as ColorDrawable).color info.description = StringUtils.trimToNull(model.description.value) info.color = model.color.value DateUtils.tzRegistry.getTimeZone(time_zone.selectedItem as String)?.let { tz -> val tzId = model.timezone.value if (tzId.isNullOrBlank()) { model.timezoneError.value = getString(R.string.create_calendar_time_zone_required) ok = false } else { DateUtils.tzRegistry.getTimeZone(tzId)?.let { tz -> val cal = Calendar() cal.components += tz.vTimeZone info.timeZone = cal.toString() } when (type.checkedRadioButtonId) { R.id.type_events -> info.supportsVEVENT = true R.id.type_tasks -> info.supportsVTODO = true R.id.type_events_and_tasks -> { info.supportsVEVENT = true info.supportsVTODO = true } model.timezoneError.value = null } if (ok) { val supportsVEVENT = model.supportVEVENT.value ?: false val supportsVTODO = model.supportVTODO.value ?: false val supportsVJOURNAL = model.supportVJOURNAL.value ?: false if (!supportsVEVENT && !supportsVTODO && !supportsVJOURNAL) { ok = false model.typeError.value = "" } else model.typeError.value = null info.type = CollectionInfo.Type.CALENDAR CreateCollectionFragment.newInstance(account, info).show(supportFragmentManager, null) info.supportsVEVENT = supportsVEVENT info.supportsVTODO = supportsVTODO info.supportsVJOURNAL = supportsVJOURNAL if (ok) CreateCollectionFragment.newInstance(model.account!!, info).show(supportFragmentManager, null) } } class HomesetAdapter( context: Context ): ArrayAdapter<String>(context, android.R.layout.simple_list_item_1, android.R.id.text1) { init { setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item) } override fun getView(position: Int, convertView: View?, parent: ViewGroup): View { val data = getItem(position)!! val v = super.getView(position, convertView, parent) v.findViewById<TextView>(android.R.id.text1).apply { setSingleLine() ellipsize = TextUtils.TruncateAt.START } return v } override fun onCreateLoader(id: Int, args: Bundle?) = AccountInfoLoader(this, account) override fun getDropDownView(position: Int, convertView: View?, parent: ViewGroup): View { val data = getItem(position)!! val v = super.getDropDownView(position, convertView, parent) v.findViewById<TextView>(android.R.id.text1).apply { ellipsize = TextUtils.TruncateAt.START } return v } override fun onLoadFinished(loader: Loader<AccountInfo>, info: AccountInfo?) { val timeZones = TimeZone.getAvailableIDs() time_zone.adapter = ArrayAdapter<String>(this, android.R.layout.simple_spinner_dropdown_item, timeZones) } // select system time zone val defaultTimeZone = TimeZone.getDefault().id for (i in 0 until timeZones.size) if (timeZones[i] == defaultTimeZone) { time_zone.setSelection(i) break class TimeZoneAdapter( context: Context ): ArrayAdapter<String>(context, android.R.layout.simple_list_item_1, android.R.id.text1) { val tz = TimeZone.getAvailableIDs() override fun getFilter(): Filter { return object: Filter() { override fun performFiltering(constraint: CharSequence?): FilterResults { val filtered = constraint?.let { tz.filter { it.contains(constraint, true) } } ?: listOf() val results = FilterResults() results.values = filtered results.count = filtered.size return results } override fun publishResults(constraint: CharSequence?, results: FilterResults) { clear() @Suppress("UNCHECKED_CAST") addAll(results.values as List<String>) if (results.count >= 0) notifyDataSetChanged() else notifyDataSetInvalidated() } } } info?.let { home_sets.adapter = ArrayAdapter<String>(this, android.R.layout.simple_spinner_dropdown_item, info.homeSets) } class Model( application: Application ): AndroidViewModel(application) { class TimeZoneInfo( val id: String, val displayName: String ) { override fun toString() = id } override fun onLoaderReset(loader: Loader<AccountInfo>) {} var account: Account? = null val displayName = MutableLiveData<String>() val displayNameError = MutableLiveData<String>() val description = MutableLiveData<String>() val color = MutableLiveData<Int>() class AccountInfo { val homeSets = LinkedList<String>() val homeSets = MutableLiveData<SpinnerAdapter>() val idxHomeSet = MutableLiveData<Int>() val timezones = TimeZoneAdapter(application) val timezone = MutableLiveData<String>() val timezoneError = MutableLiveData<String>() val typeError = MutableLiveData<String>() val supportVEVENT = MutableLiveData<Boolean>() val supportVTODO = MutableLiveData<Boolean>() val supportVJOURNAL = MutableLiveData<Boolean>() fun initialize(account: Account) { synchronized(this) { if (this.account != null) return this.account = account } class AccountInfoLoader( context: Context, val account: Account ): AsyncTaskLoader<AccountInfo>(context) { color.value = Constants.DAVDROID_GREEN_RGBA timezone.value = TimeZone.getDefault().id override fun onStartLoading() = forceLoad() supportVEVENT.value = true supportVTODO.value = true supportVJOURNAL.value = true override fun loadInBackground(): AccountInfo? { val info = AccountInfo() ServiceDB.OpenHelper(context).use { dbHelper -> thread { // load account info ServiceDB.OpenHelper(getApplication()).use { dbHelper -> val adapter = HomesetAdapter(getApplication()) val db = dbHelper.readableDatabase db.query(ServiceDB.Services._TABLE, arrayOf(ServiceDB.Services.ID), "${ServiceDB.Services.ACCOUNT_NAME}=? AND ${ServiceDB.Services.SERVICE}=?", arrayOf(account.name, ServiceDB.Services.SERVICE_CALDAV), null, null, null).use { cursor -> if (!cursor.moveToNext()) return null if (cursor.moveToNext()) { val strServiceID = cursor.getString(0) db.query(ServiceDB.HomeSets._TABLE, arrayOf(ServiceDB.HomeSets.URL), "${ServiceDB.HomeSets.SERVICE_ID}=?", arrayOf(strServiceID), null, null, null).use { c -> while (c.moveToNext()) info.homeSets += c.getString(0) adapter.add(c.getString(0)) } } } homeSets.postValue(adapter) idxHomeSet.postValue(0) } return info } } } }
app/src/main/java/at/bitfire/davdroid/ui/CreateCollectionFragment.kt +5 −0 Original line number Diff line number Diff line Loading @@ -171,6 +171,11 @@ class CreateCollectionFragment: DialogFragment(), LoaderManager.LoaderCallbacks< attribute(null, "name", "VTODO") endTag(XmlUtils.NS_CALDAV, "comp") } if (info.supportsVJOURNAL) { startTag(XmlUtils.NS_CALDAV, "comp") attribute(null, "name", "VJOURNAL") endTag(XmlUtils.NS_CALDAV, "comp") } endTag(XmlUtils.NS_CALDAV, "supported-calendar-component-set") } Loading
app/src/main/res/layout/activity_create_calendar.xml +122 −97 File changed.Preview size limit exceeded, changes collapsed. Show changes