From 579bc8bb666a857ba3da705115d848840e3482e6 Mon Sep 17 00:00:00 2001 From: Naveen Date: Sun, 15 Jan 2023 00:10:07 +0530 Subject: [PATCH 01/12] Use UUID for tasks too --- .../calendar/pro/activities/TaskActivity.kt | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) 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 338ab3fe7..ac37dc165 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 @@ -351,6 +351,11 @@ class TaskActivity : SimpleActivity() { } val wasRepeatable = mTask.repeatInterval > 0 + val newImportId = if (mTask.id != null) { + mTask.importId + } else { + UUID.randomUUID().toString().replace("-", "") + System.currentTimeMillis().toString() + } val reminders = getReminders() if (!task_all_day.isChecked) { @@ -393,6 +398,7 @@ class TaskActivity : SimpleActivity() { updateTaskCompletion(copy(startTS = mOriginalStartTS), true) } } + importId = newImportId flags = mTask.flags.addBitIf(task_all_day.isChecked, FLAG_ALL_DAY) lastUpdated = System.currentTimeMillis() eventType = mEventTypeId @@ -458,7 +464,7 @@ class TaskActivity : SimpleActivity() { when (it) { 0 -> { ensureBackgroundThread { - eventsHelper.addEventRepetitionException(mTask.id!!, mTaskOccurrenceTS, true) + eventsHelper.addEventRepetitionException(mTask.id!!, mTaskOccurrenceTS, addToCalDAV = false) mTask.apply { parentId = id!!.toLong() id = null @@ -610,7 +616,6 @@ class TaskActivity : SimpleActivity() { } } - private fun updateDateText() { task_date.text = Formatter.getDate(this, mTaskDateTime) } @@ -766,7 +771,6 @@ class TaskActivity : SimpleActivity() { } } - private fun showRepeatIntervalDialog() { showEventRepeatIntervalDialog(mRepeatInterval) { setRepeatInterval(it) From 635fa436c78a0a9c50bcb045937dd38afa54c76a Mon Sep 17 00:00:00 2001 From: Naveen Date: Sun, 15 Jan 2023 02:37:31 +0530 Subject: [PATCH 02/12] Add option to export tasks --- .../calendar/pro/activities/MainActivity.kt | 8 +- .../pro/dialogs/ExportEventsDialog.kt | 19 +++- .../calendar/pro/extensions/Activity.kt | 5 +- .../calendar/pro/helpers/Config.kt | 8 ++ .../calendar/pro/helpers/Constants.kt | 5 + .../calendar/pro/helpers/EventsHelper.kt | 15 ++- .../calendar/pro/helpers/IcsExporter.kt | 101 ++++++++++++------ .../calendar/pro/interfaces/EventsDao.kt | 15 +-- .../main/res/layout/dialog_export_events.xml | 59 +++++++++- 9 files changed, 181 insertions(+), 54 deletions(-) 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 b99649ee2..7277c01b7 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 @@ -1129,8 +1129,8 @@ class MainActivity : SimpleActivity(), RefreshRecyclerViewListener { } } } else { - handlePermission(PERMISSION_WRITE_STORAGE) { - if (it) { + handlePermission(PERMISSION_WRITE_STORAGE) { granted -> + if (granted) { ExportEventsDialog(this, config.lastExportPath, false) { file, eventTypes -> getFileOutputStream(file.toFileDirItem(this), true) { exportEventsTo(eventTypes, it) @@ -1147,9 +1147,9 @@ class MainActivity : SimpleActivity(), RefreshRecyclerViewListener { if (events.isEmpty()) { toast(R.string.no_entries_for_exporting) } else { - IcsExporter().exportEvents(this, outputStream, events, true) { + IcsExporter(this).exportEvents(outputStream, events, true) { result -> toast( - when (it) { + when (result) { ExportResult.EXPORT_OK -> R.string.exporting_successful ExportResult.EXPORT_PARTIAL -> R.string.exporting_some_entries_failed else -> R.string.exporting_failed diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/dialogs/ExportEventsDialog.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/dialogs/ExportEventsDialog.kt index a0af0d22c..7d149ad77 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/dialogs/ExportEventsDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/dialogs/ExportEventsDialog.kt @@ -17,13 +17,22 @@ class ExportEventsDialog( val activity: SimpleActivity, val path: String, val hidePath: Boolean, val callback: (file: File, eventTypes: ArrayList) -> Unit ) { - private var realPath = if (path.isEmpty()) activity.internalStoragePath else path + private var realPath = path.ifEmpty { activity.internalStoragePath } private val config = activity.config init { val view = (activity.layoutInflater.inflate(R.layout.dialog_export_events, null) as ViewGroup).apply { export_events_folder.setText(activity.humanizePath(realPath)) export_events_filename.setText("${activity.getString(R.string.events)}_${activity.getCurrentFormattedDateTime()}") + + export_events_checkbox.isChecked = config.exportEvents + export_events_checkbox_holder.setOnClickListener { + export_events_checkbox.toggle() + } + export_tasks_checkbox.isChecked = config.exportTasks + export_tasks_checkbox_holder.setOnClickListener { + export_tasks_checkbox.toggle() + } export_past_events_checkbox.isChecked = config.exportPastEvents export_past_events_checkbox_holder.setOnClickListener { export_past_events_checkbox.toggle() @@ -70,8 +79,12 @@ class ExportEventsDialog( } ensureBackgroundThread { - config.lastExportPath = file.absolutePath.getParentPath() - config.exportPastEvents = view.export_past_events_checkbox.isChecked + config.apply { + lastExportPath = file.absolutePath.getParentPath() + exportEvents = view.export_events_checkbox.isChecked + exportTasks = view.export_tasks_checkbox.isChecked + exportPastEvents = view.export_past_events_checkbox.isChecked + } val eventTypes = (view.export_events_types_list.adapter as FilterEventTypeAdapter).getSelectedItemsList() callback(file, eventTypes) diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/extensions/Activity.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/extensions/Activity.kt index 407ffaaa5..098a83d08 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/extensions/Activity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/extensions/Activity.kt @@ -13,7 +13,6 @@ import com.simplemobiletools.commons.helpers.ensureBackgroundThread import com.simplemobiletools.commons.models.RadioItem import java.io.File import java.util.* -import kotlin.collections.ArrayList fun BaseSimpleActivity.shareEvents(ids: List) { ensureBackgroundThread { @@ -29,8 +28,8 @@ fun BaseSimpleActivity.shareEvents(ids: List) { } getFileOutputStream(file.toFileDirItem(this), true) { - IcsExporter().exportEvents(this, it, events, false) { - if (it == IcsExporter.ExportResult.EXPORT_OK) { + IcsExporter(this).exportEvents(it, events, false) { result -> + if (result == IcsExporter.ExportResult.EXPORT_OK) { sharePathIntent(file.absolutePath, BuildConfig.APPLICATION_ID) } } 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 fcb435ff4..5217954f1 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 @@ -223,6 +223,14 @@ class Config(context: Context) : BaseConfig(context) { get() = prefs.getString(LAST_EXPORT_PATH, "")!! set(lastExportPath) = prefs.edit().putString(LAST_EXPORT_PATH, lastExportPath).apply() + var exportEvents: Boolean + get() = prefs.getBoolean(EXPORT_EVENTS, true) + set(exportEvents) = prefs.edit().putBoolean(EXPORT_EVENTS, exportEvents).apply() + + var exportTasks: Boolean + get() = prefs.getBoolean(EXPORT_TASKS, true) + set(exportTasks) = prefs.edit().putBoolean(EXPORT_TASKS, exportTasks).apply() + var exportPastEvents: Boolean get() = prefs.getBoolean(EXPORT_PAST_EVENTS, false) set(exportPastEvents) = prefs.edit().putBoolean(EXPORT_PAST_EVENTS, exportPastEvents).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 5bbd77ca9..d589c79c3 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 @@ -116,6 +116,8 @@ const val ADD_ANNIVERSARIES_AUTOMATICALLY = "add_anniversaries_automatically" const val BIRTHDAY_REMINDERS = "birthday_reminders" const val ANNIVERSARY_REMINDERS = "anniversary_reminders" const val LAST_EXPORT_PATH = "last_export_path" +const val EXPORT_EVENTS = "export_events" +const val EXPORT_TASKS = "export_tasks" const val EXPORT_PAST_EVENTS = "export_past_events" const val WEEKLY_VIEW_ITEM_HEIGHT_MULTIPLIER = "weekly_view_item_height_multiplier" const val WEEKLY_VIEW_DAYS = "weekly_view_days" @@ -144,6 +146,8 @@ const val CALENDAR_PRODID = "PRODID:-//Simple Mobile Tools//NONSGML Event Calend const val CALENDAR_VERSION = "VERSION:2.0" const val BEGIN_EVENT = "BEGIN:VEVENT" const val END_EVENT = "END:VEVENT" +const val BEGIN_TODO = "BEGIN:VTODO" +const val END_TODO = "END:VTODO" const val BEGIN_ALARM = "BEGIN:VALARM" const val END_ALARM = "END:VALARM" const val DTSTART = "DTSTART" @@ -182,6 +186,7 @@ const val UNTIL = "UNTIL" const val COUNT = "COUNT" const val INTERVAL = "INTERVAL" const val CONFIRMED = "CONFIRMED" +const val COMPLETED = "COMPLETED" const val VALUE = "VALUE" const val DATE = "DATE" 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 3bc102b78..47e5e37c2 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 @@ -522,13 +522,24 @@ class EventsHelper(val context: Context) { fun getEventsToExport(eventTypes: ArrayList): ArrayList { val currTS = getNowSeconds() var events = ArrayList() + val tasks = ArrayList() if (config.exportPastEvents) { events.addAll(eventsDB.getAllEventsWithTypes(eventTypes)) + if (config.exportTasks) { + tasks.addAll(eventsDB.getAllTasksWithTypes(eventTypes)) + } } else { - events.addAll(eventsDB.getOneTimeFutureEventsWithTypes(currTS, eventTypes)) - events.addAll(eventsDB.getRepeatableFutureEventsWithTypes(currTS, eventTypes)) + events.addAll(eventsDB.getAllFutureEventsWithTypes(currTS, eventTypes)) + if (config.exportTasks) { + tasks.addAll(eventsDB.getAllFutureTasksWithTypes(currTS, eventTypes)) + } } + tasks.forEach { + updateIsTaskCompleted(it) + } + events.addAll(tasks) + events = events.distinctBy { it.id } as ArrayList return events } diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/helpers/IcsExporter.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/helpers/IcsExporter.kt index f6d290fe0..037fddfa3 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/helpers/IcsExporter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/helpers/IcsExporter.kt @@ -17,7 +17,7 @@ import java.io.BufferedWriter import java.io.OutputStream import java.io.OutputStreamWriter -class IcsExporter { +class IcsExporter(private val activity: BaseSimpleActivity) { enum class ExportResult { EXPORT_FAIL, EXPORT_OK, EXPORT_PARTIAL } @@ -26,9 +26,10 @@ class IcsExporter { private var eventsExported = 0 private var eventsFailed = 0 private var calendars = ArrayList() + private val reminderLabel = activity.getString(R.string.reminder) + private val exportTime = Formatter.getExportedTime(System.currentTimeMillis()) fun exportEvents( - activity: BaseSimpleActivity, outputStream: OutputStream?, events: ArrayList, showExportingToast: Boolean, @@ -40,15 +41,11 @@ class IcsExporter { } ensureBackgroundThread { - val reminderLabel = activity.getString(R.string.reminder) - val exportTime = Formatter.getExportedTime(System.currentTimeMillis()) - calendars = activity.calDAVHelper.getCalDAVCalendars("", false) if (showExportingToast) { activity.toast(R.string.exporting) } - object : BufferedWriter(OutputStreamWriter(outputStream, Charsets.UTF_8)) { val lineSeparator = "\r\n" @@ -66,34 +63,11 @@ class IcsExporter { out.writeLn(CALENDAR_PRODID) out.writeLn(CALENDAR_VERSION) for (event in events) { - out.writeLn(BEGIN_EVENT) - event.title.replace("\n", "\\n").let { if (it.isNotEmpty()) out.writeLn("$SUMMARY:$it") } - event.importId.let { if (it.isNotEmpty()) out.writeLn("$UID$it") } - event.eventType.let { out.writeLn("$CATEGORY_COLOR${activity.eventTypesDB.getEventTypeWithId(it)?.color}") } - event.eventType.let { out.writeLn("$CATEGORIES${activity.eventTypesDB.getEventTypeWithId(it)?.title}") } - event.lastUpdated.let { out.writeLn("$LAST_MODIFIED:${Formatter.getExportedTime(it)}") } - event.location.let { if (it.isNotEmpty()) out.writeLn("$LOCATION:$it") } - event.availability.let { out.writeLn("$TRANSP${if (it == Events.AVAILABILITY_FREE) TRANSPARENT else OPAQUE}") } - - if (event.getIsAllDay()) { - out.writeLn("$DTSTART;$VALUE=$DATE:${Formatter.getDayCodeFromTS(event.startTS)}") - out.writeLn("$DTEND;$VALUE=$DATE:${Formatter.getDayCodeFromTS(event.endTS + TWELVE_HOURS)}") + if (event.isTask()) { + writeTodo(out, event) } else { - event.startTS.let { out.writeLn("$DTSTART:${Formatter.getExportedTime(it * 1000L)}") } - event.endTS.let { out.writeLn("$DTEND:${Formatter.getExportedTime(it * 1000L)}") } + writeEvent(out, event) } - event.hasMissingYear().let { out.writeLn("$MISSING_YEAR${if (it) 1 else 0}") } - - out.writeLn("$DTSTAMP$exportTime") - out.writeLn("$STATUS$CONFIRMED") - Parser().getRepeatCode(event).let { if (it.isNotEmpty()) out.writeLn("$RRULE$it") } - - fillDescription(event.description.replace("\n", "\\n"), out) - fillReminders(event, out, reminderLabel) - fillIgnoredOccurrences(event, out) - - eventsExported++ - out.writeLn(END_EVENT) } out.writeLn(END_CALENDAR) } @@ -153,4 +127,67 @@ class IcsExporter { index += MAX_LINE_LENGTH } } + + private fun writeEvent(writer: BufferedWriter, event: Event) { + with(writer) { + writeLn(BEGIN_EVENT) + event.title.replace("\n", "\\n").let { if (it.isNotEmpty()) writeLn("$SUMMARY:$it") } + event.importId.let { if (it.isNotEmpty()) writeLn("$UID$it") } + writeLn("$CATEGORY_COLOR${activity.eventTypesDB.getEventTypeWithId(event.eventType)?.color}") + writeLn("$CATEGORIES${activity.eventTypesDB.getEventTypeWithId(event.eventType)?.title}") + writeLn("$LAST_MODIFIED:${Formatter.getExportedTime(event.lastUpdated)}") + writeLn("$TRANSP${if (event.availability == Events.AVAILABILITY_FREE) TRANSPARENT else OPAQUE}") + + if (event.getIsAllDay()) { + writeLn("$DTSTART;$VALUE=$DATE:${Formatter.getDayCodeFromTS(event.startTS)}") + writeLn("$DTEND;$VALUE=$DATE:${Formatter.getDayCodeFromTS(event.endTS + TWELVE_HOURS)}") + } else { + writeLn("$DTSTART:${Formatter.getExportedTime(event.startTS * 1000L)}") + writeLn("$DTEND:${Formatter.getExportedTime(event.endTS * 1000L)}") + } + writeLn("$MISSING_YEAR${if (event.hasMissingYear()) 1 else 0}") + + writeLn("$DTSTAMP$exportTime") + writeLn("$STATUS$CONFIRMED") + Parser().getRepeatCode(event).let { if (it.isNotEmpty()) writeLn("$RRULE$it") } + + fillDescription(event.description.replace("\n", "\\n"), writer) + fillReminders(event, writer, reminderLabel) + fillIgnoredOccurrences(event, writer) + + eventsExported++ + writeLn(END_EVENT) + } + } + + private fun writeTodo(writer: BufferedWriter, task: Event) { + with(writer) { + writeLn(BEGIN_TODO) + task.title.replace("\n", "\\n").let { if (it.isNotEmpty()) writeLn("$SUMMARY:$it") } + task.importId.let { if (it.isNotEmpty()) writeLn("$UID$it") } + writeLn("$CATEGORY_COLOR${activity.eventTypesDB.getEventTypeWithId(task.eventType)?.color}") + writeLn("$CATEGORIES${activity.eventTypesDB.getEventTypeWithId(task.eventType)?.title}") + writeLn("$LAST_MODIFIED:${Formatter.getExportedTime(task.lastUpdated)}") + task.location.let { if (it.isNotEmpty()) writeLn("$LOCATION:$it") } + + if (task.getIsAllDay()) { + writeLn("$DTSTART;$VALUE=$DATE:${Formatter.getDayCodeFromTS(task.startTS)}") + } else { + writeLn("$DTSTART:${Formatter.getExportedTime(task.startTS * 1000L)}") + } + + writeLn("$DTSTAMP$exportTime") + if (task.isTaskCompleted()) { + writeLn("$STATUS$COMPLETED") + } + Parser().getRepeatCode(task).let { if (it.isNotEmpty()) writeLn("$RRULE$it") } + + fillDescription(task.description.replace("\n", "\\n"), writer) + fillReminders(task, writer, reminderLabel) + fillIgnoredOccurrences(task, writer) + + eventsExported++ + writeLn(END_TODO) + } + } } diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/interfaces/EventsDao.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/interfaces/EventsDao.kt index 83128aa27..8bfdb6330 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/interfaces/EventsDao.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/interfaces/EventsDao.kt @@ -15,6 +15,15 @@ interface EventsDao { @Query("SELECT * FROM events WHERE event_type IN (:eventTypeIds) AND type = $TYPE_EVENT") fun getAllEventsWithTypes(eventTypeIds: List): List + @Query("SELECT * FROM events WHERE event_type IN (:eventTypeIds) AND type = $TYPE_TASK") + fun getAllTasksWithTypes(eventTypeIds: List): List + + @Query("SELECT * FROM events WHERE end_ts > :currTS AND event_type IN (:eventTypeIds) AND type = $TYPE_EVENT") + fun getAllFutureEventsWithTypes(currTS: Long, eventTypeIds: List): List + + @Query("SELECT * FROM events WHERE end_ts > :currTS AND event_type IN (:eventTypeIds) AND type = $TYPE_TASK") + fun getAllFutureTasksWithTypes(currTS: Long, eventTypeIds: List): List + @Query("SELECT * FROM events WHERE id = :id AND type = $TYPE_EVENT") fun getEventWithId(id: Long): Event? @@ -42,9 +51,6 @@ interface EventsDao { @Query("SELECT * FROM events WHERE start_ts <= :toTS AND end_ts >= :fromTS AND start_ts != 0 AND repeat_interval = 0 AND event_type IN (:eventTypeIds) AND (title LIKE :searchQuery OR location LIKE :searchQuery OR description LIKE :searchQuery)") fun getOneTimeEventsFromToWithTypesForSearch(toTS: Long, fromTS: Long, eventTypeIds: List, searchQuery: String): List - @Query("SELECT * FROM events WHERE end_ts > :toTS AND repeat_interval = 0 AND event_type IN (:eventTypeIds) AND type = $TYPE_EVENT") - fun getOneTimeFutureEventsWithTypes(toTS: Long, eventTypeIds: List): List - @Query("SELECT * FROM events WHERE start_ts <= :toTS AND repeat_interval != 0") fun getRepeatableEventsOrTasksWithTypes(toTS: Long): List @@ -57,9 +63,6 @@ interface EventsDao { @Query("SELECT * FROM events WHERE start_ts <= :toTS AND start_ts != 0 AND repeat_interval != 0 AND event_type IN (:eventTypeIds) AND (title LIKE :searchQuery OR location LIKE :searchQuery OR description LIKE :searchQuery)") fun getRepeatableEventsOrTasksWithTypesForSearch(toTS: Long, eventTypeIds: List, searchQuery: String): List - @Query("SELECT * FROM events WHERE repeat_interval != 0 AND (repeat_limit == 0 OR repeat_limit > :currTS) AND event_type IN (:eventTypeIds) AND type = $TYPE_EVENT") - fun getRepeatableFutureEventsWithTypes(currTS: Long, eventTypeIds: List): List - @Query("SELECT * FROM events WHERE id IN (:ids) AND import_id != \"\" AND type = $TYPE_EVENT") fun getEventsByIdsWithImportIds(ids: List): List diff --git a/app/src/main/res/layout/dialog_export_events.xml b/app/src/main/res/layout/dialog_export_events.xml index 304e945f9..0eaf010b5 100644 --- a/app/src/main/res/layout/dialog_export_events.xml +++ b/app/src/main/res/layout/dialog_export_events.xml @@ -48,15 +48,66 @@ + + + + + + + + + + + + + + + android:paddingEnd="@dimen/activity_margin"> + android:text="@string/export_past_entries" /> From 01c8a4c977ecbbe3de3dbc4782b88a2fc9323598 Mon Sep 17 00:00:00 2001 From: Naveen Date: Sun, 15 Jan 2023 02:47:56 +0530 Subject: [PATCH 03/12] Respect config when exporting events --- .../calendar/pro/dialogs/ExportEventsDialog.kt | 4 ++-- .../simplemobiletools/calendar/pro/helpers/Config.kt | 2 +- .../calendar/pro/helpers/EventsHelper.kt | 10 +++++++--- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/dialogs/ExportEventsDialog.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/dialogs/ExportEventsDialog.kt index 7d149ad77..f2bf625b8 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/dialogs/ExportEventsDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/dialogs/ExportEventsDialog.kt @@ -33,7 +33,7 @@ class ExportEventsDialog( export_tasks_checkbox_holder.setOnClickListener { export_tasks_checkbox.toggle() } - export_past_events_checkbox.isChecked = config.exportPastEvents + export_past_events_checkbox.isChecked = config.exportPastEntries export_past_events_checkbox_holder.setOnClickListener { export_past_events_checkbox.toggle() } @@ -83,7 +83,7 @@ class ExportEventsDialog( lastExportPath = file.absolutePath.getParentPath() exportEvents = view.export_events_checkbox.isChecked exportTasks = view.export_tasks_checkbox.isChecked - exportPastEvents = view.export_past_events_checkbox.isChecked + exportPastEntries = view.export_past_events_checkbox.isChecked } val eventTypes = (view.export_events_types_list.adapter as FilterEventTypeAdapter).getSelectedItemsList() 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 5217954f1..6e7d9e9d5 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 @@ -231,7 +231,7 @@ class Config(context: Context) : BaseConfig(context) { get() = prefs.getBoolean(EXPORT_TASKS, true) set(exportTasks) = prefs.edit().putBoolean(EXPORT_TASKS, exportTasks).apply() - var exportPastEvents: Boolean + var exportPastEntries: Boolean get() = prefs.getBoolean(EXPORT_PAST_EVENTS, false) set(exportPastEvents) = prefs.edit().putBoolean(EXPORT_PAST_EVENTS, exportPastEvents).apply() 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 47e5e37c2..bcd00625e 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 @@ -523,13 +523,17 @@ class EventsHelper(val context: Context) { val currTS = getNowSeconds() var events = ArrayList() val tasks = ArrayList() - if (config.exportPastEvents) { - events.addAll(eventsDB.getAllEventsWithTypes(eventTypes)) + if (config.exportPastEntries) { + if (config.exportEvents) { + events.addAll(eventsDB.getAllEventsWithTypes(eventTypes)) + } if (config.exportTasks) { tasks.addAll(eventsDB.getAllTasksWithTypes(eventTypes)) } } else { - events.addAll(eventsDB.getAllFutureEventsWithTypes(currTS, eventTypes)) + if (config.exportEvents) { + events.addAll(eventsDB.getAllFutureEventsWithTypes(currTS, eventTypes)) + } if (config.exportTasks) { tasks.addAll(eventsDB.getAllFutureTasksWithTypes(currTS, eventTypes)) } From be8b2a3fe5c8886a23e444bd1a0bf50f2a51ce6c Mon Sep 17 00:00:00 2001 From: Naveen Date: Sun, 15 Jan 2023 03:37:15 +0530 Subject: [PATCH 04/12] Rename todo to task --- .../simplemobiletools/calendar/pro/helpers/Constants.kt | 4 ++-- .../simplemobiletools/calendar/pro/helpers/IcsExporter.kt | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) 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 d589c79c3..a81f5b7ed 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 @@ -146,8 +146,8 @@ const val CALENDAR_PRODID = "PRODID:-//Simple Mobile Tools//NONSGML Event Calend const val CALENDAR_VERSION = "VERSION:2.0" const val BEGIN_EVENT = "BEGIN:VEVENT" const val END_EVENT = "END:VEVENT" -const val BEGIN_TODO = "BEGIN:VTODO" -const val END_TODO = "END:VTODO" +const val BEGIN_TASK = "BEGIN:VTODO" +const val END_TASK = "END:VTODO" const val BEGIN_ALARM = "BEGIN:VALARM" const val END_ALARM = "END:VALARM" const val DTSTART = "DTSTART" diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/helpers/IcsExporter.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/helpers/IcsExporter.kt index 037fddfa3..b286d7c92 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/helpers/IcsExporter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/helpers/IcsExporter.kt @@ -64,7 +64,7 @@ class IcsExporter(private val activity: BaseSimpleActivity) { out.writeLn(CALENDAR_VERSION) for (event in events) { if (event.isTask()) { - writeTodo(out, event) + writeTask(out, event) } else { writeEvent(out, event) } @@ -160,9 +160,9 @@ class IcsExporter(private val activity: BaseSimpleActivity) { } } - private fun writeTodo(writer: BufferedWriter, task: Event) { + private fun writeTask(writer: BufferedWriter, task: Event) { with(writer) { - writeLn(BEGIN_TODO) + writeLn(BEGIN_TASK) task.title.replace("\n", "\\n").let { if (it.isNotEmpty()) writeLn("$SUMMARY:$it") } task.importId.let { if (it.isNotEmpty()) writeLn("$UID$it") } writeLn("$CATEGORY_COLOR${activity.eventTypesDB.getEventTypeWithId(task.eventType)?.color}") @@ -187,7 +187,7 @@ class IcsExporter(private val activity: BaseSimpleActivity) { fillIgnoredOccurrences(task, writer) eventsExported++ - writeLn(END_TODO) + writeLn(END_TASK) } } } From 7c573fc3b8043a5db6edbf763e45ddcedf2a097b Mon Sep 17 00:00:00 2001 From: Naveen Date: Sun, 15 Jan 2023 03:39:50 +0530 Subject: [PATCH 05/12] Add id to view --- app/src/main/res/layout/dialog_export_events.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/res/layout/dialog_export_events.xml b/app/src/main/res/layout/dialog_export_events.xml index 0eaf010b5..72ba0db31 100644 --- a/app/src/main/res/layout/dialog_export_events.xml +++ b/app/src/main/res/layout/dialog_export_events.xml @@ -94,6 +94,7 @@ Date: Sun, 15 Jan 2023 05:13:23 +0530 Subject: [PATCH 06/12] Add support for importing tasks --- .../calendar/pro/helpers/IcsImporter.kt | 50 ++++++++++++++----- 1 file changed, 37 insertions(+), 13 deletions(-) diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/helpers/IcsImporter.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/helpers/IcsImporter.kt index 7921d5501..09079be28 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/helpers/IcsImporter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/helpers/IcsImporter.kt @@ -5,6 +5,7 @@ import com.simplemobiletools.calendar.pro.R import com.simplemobiletools.calendar.pro.activities.SimpleActivity import com.simplemobiletools.calendar.pro.extensions.eventsDB import com.simplemobiletools.calendar.pro.extensions.eventsHelper +import com.simplemobiletools.calendar.pro.extensions.updateTaskCompletion import com.simplemobiletools.calendar.pro.helpers.IcsImporter.ImportResult.IMPORT_FAIL import com.simplemobiletools.calendar.pro.helpers.IcsImporter.ImportResult.IMPORT_NOTHING_NEW import com.simplemobiletools.calendar.pro.helpers.IcsImporter.ImportResult.IMPORT_OK @@ -17,6 +18,7 @@ import com.simplemobiletools.commons.extensions.showErrorToast import com.simplemobiletools.commons.helpers.HOUR_SECONDS import org.joda.time.DateTimeZone import java.io.File +import kotlin.math.min class IcsImporter(val activity: SimpleActivity) { enum class ImportResult { @@ -45,7 +47,9 @@ class IcsImporter(val activity: SimpleActivity) { private var isNotificationDescription = false private var isProperReminderAction = false private var isSequence = false + private var curType = TYPE_EVENT private var isParsingEvent = false + private var isParsingTask = false private var curReminderTriggerMinutes = REMINDER_OFF private var curReminderTriggerAction = REMINDER_NOTIFICATION private val eventsHelper = activity.eventsHelper @@ -89,8 +93,13 @@ class IcsImporter(val activity: SimpleActivity) { resetValues() curEventTypeId = defaultEventTypeId isParsingEvent = true + } else if (line.trim() == BEGIN_TASK) { + resetValues() + curEventTypeId = defaultEventTypeId + isParsingTask = true + curType = TYPE_TASK } else if (line.startsWith(DTSTART)) { - if (isParsingEvent) { + if (isParsingEvent || isParsingTask) { curStart = getTimestamp(line.substring(DTSTART.length)) if (curRrule != "") { @@ -144,6 +153,14 @@ class IcsImporter(val activity: SimpleActivity) { if (line.substring(MISSING_YEAR.length) == "1") { curFlags = curFlags or FLAG_MISSING_YEAR } + } else if (line.startsWith(STATUS)) { + if (isParsingTask && line.substring(STATUS.length) == COMPLETED) { + curFlags = curFlags or FLAG_TASK_COMPLETED + } + } else if (line.startsWith(COMPLETED)) { + if (isParsingTask && line.substring(COMPLETED.length).trim().isNotEmpty()) { + curFlags = curFlags or FLAG_TASK_COMPLETED + } } else if (line.startsWith(CATEGORIES) && !overrideFileEventTypes) { val categories = line.substring(CATEGORIES.length) tryAddCategories(categories) @@ -182,11 +199,12 @@ class IcsImporter(val activity: SimpleActivity) { curReminderActions.add(curReminderTriggerAction) } isNotificationDescription = false - } else if (line.trim() == END_EVENT) { - isParsingEvent = false - if (curStart != -1L && curEnd == -1L) { + } else if (line.trim() == END_EVENT || line.trim() == END_TASK) { + if (curStart != -1L && (curEnd == -1L || isParsingTask)) { curEnd = curStart } + isParsingEvent = false + isParsingTask = false if (curTitle.isEmpty() || curStart == -1L) { line = curLine @@ -194,8 +212,7 @@ class IcsImporter(val activity: SimpleActivity) { } // repeating event exceptions can have the same import id as their parents, so pick the latest event to update - val eventToUpdate = - existingEvents.filter { curImportId.isNotEmpty() && curImportId == it.importId }.sortedByDescending { it.lastUpdated }.firstOrNull() + val eventToUpdate = existingEvents.filter { curImportId.isNotEmpty() && curImportId == it.importId }.maxByOrNull { it.lastUpdated } if (eventToUpdate != null && eventToUpdate.lastUpdated >= curLastModified) { eventsAlreadyExist++ line = curLine @@ -238,10 +255,11 @@ class IcsImporter(val activity: SimpleActivity) { 0, curLastModified, source, - curAvailability + curAvailability, + type = curType ) - if (isAllDay && curEnd > curStart) { + if (isAllDay && curEnd > curStart && !event.isTask()) { event.endTS -= TWELVE_HOURS // fix some glitches related to daylight saving shifts if (event.startTS - event.endTS == HOUR_SECONDS.toLong()) { @@ -264,13 +282,13 @@ class IcsImporter(val activity: SimpleActivity) { // if an event belongs to a sequence insert it immediately, to avoid some glitches with linked events if (isSequence) { if (curRecurrenceDayCode.isEmpty()) { - eventsHelper.insertEvent(event, true, false) + eventsHelper.insertEvent(event, addToCalDAV = !event.isTask(), showToasts = false) } else { // if an event contains the RECURRENCE-ID field, it is an exception to a recurring event, so update its parent too val parentEvent = activity.eventsDB.getEventWithImportId(event.importId) if (parentEvent != null && !parentEvent.repetitionExceptions.contains(curRecurrenceDayCode)) { parentEvent.addRepetitionException(curRecurrenceDayCode) - eventsHelper.insertEvent(parentEvent, true, false) + eventsHelper.insertEvent(parentEvent, !parentEvent.isTask(), showToasts = false) event.parentId = parentEvent.id!! eventsToInsert.add(event) @@ -281,7 +299,7 @@ class IcsImporter(val activity: SimpleActivity) { } } else { event.id = eventToUpdate.id - eventsHelper.updateEvent(event, true, false) + eventsHelper.updateEvent(event, updateAtCalDAV = !event.isTask(), showToasts = false) } eventsImported++ resetValues() @@ -290,7 +308,12 @@ class IcsImporter(val activity: SimpleActivity) { } } - eventsHelper.insertEvents(eventsToInsert, true) + val (tasks, events) = eventsToInsert.partition { it.isTask() } + eventsHelper.insertEvents(tasks as ArrayList, addToCalDAV = false) + eventsHelper.insertEvents(events as ArrayList, addToCalDAV = true) + tasks.filter { it.isTaskCompleted() }.forEach { + activity.updateTaskCompletion(it, completed = true) + } } catch (e: Exception) { activity.showErrorToast(e) eventsFailed++ @@ -361,7 +384,7 @@ class IcsImporter(val activity: SimpleActivity) { return if (title.startsWith(";") && title.contains(":")) { title.substring(title.lastIndexOf(':') + 1) } else { - title.substring(1, Math.min(title.length, 180)) + title.substring(1, min(title.length, 180)) } } @@ -397,5 +420,6 @@ class IcsImporter(val activity: SimpleActivity) { isParsingEvent = false curReminderTriggerMinutes = REMINDER_OFF curReminderTriggerAction = REMINDER_NOTIFICATION + curType = TYPE_EVENT } } From e93727fd80af2098b350176b18275e365a6794f3 Mon Sep 17 00:00:00 2001 From: Naveen Date: Sun, 15 Jan 2023 18:38:48 +0530 Subject: [PATCH 07/12] Show toast and disable exporting when nothing is selected --- .../calendar/pro/dialogs/ExportEventsDialog.kt | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/dialogs/ExportEventsDialog.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/dialogs/ExportEventsDialog.kt index f2bf625b8..692791fb6 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/dialogs/ExportEventsDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/dialogs/ExportEventsDialog.kt @@ -78,11 +78,18 @@ class ExportEventsDialog( return@setOnClickListener } + val exportEventsChecked = view.export_events_checkbox.isChecked + val exportTasksChecked = view.export_tasks_checkbox.isChecked + if (!exportEventsChecked && !exportTasksChecked) { + activity.toast(R.string.no_entries_for_exporting) + return@setOnClickListener + } + ensureBackgroundThread { config.apply { lastExportPath = file.absolutePath.getParentPath() - exportEvents = view.export_events_checkbox.isChecked - exportTasks = view.export_tasks_checkbox.isChecked + exportEvents = exportEventsChecked + exportTasks = exportTasksChecked exportPastEntries = view.export_past_events_checkbox.isChecked } From c70458ec20667d675405f7cccc325b1428bee00b Mon Sep 17 00:00:00 2001 From: Naveen Date: Sun, 15 Jan 2023 18:55:37 +0530 Subject: [PATCH 08/12] Reduce vertical padding to 4dp --- app/src/main/res/layout/dialog_export_events.xml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/app/src/main/res/layout/dialog_export_events.xml b/app/src/main/res/layout/dialog_export_events.xml index 72ba0db31..0949e17f2 100644 --- a/app/src/main/res/layout/dialog_export_events.xml +++ b/app/src/main/res/layout/dialog_export_events.xml @@ -54,7 +54,7 @@ android:layout_height="wrap_content" android:layout_marginTop="@dimen/medium_margin" android:background="?attr/selectableItemBackground" - android:paddingVertical="@dimen/medium_margin" + android:paddingVertical="@dimen/small_margin" android:paddingStart="@dimen/normal_margin" android:paddingEnd="@dimen/activity_margin"> @@ -66,7 +66,7 @@ android:checked="true" android:clickable="false" android:layoutDirection="rtl" - android:padding="@dimen/medium_margin" + android:paddingHorizontal="@dimen/medium_margin" android:text="@string/export_events" /> @@ -76,7 +76,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:background="?attr/selectableItemBackground" - android:paddingVertical="@dimen/medium_margin" + android:paddingVertical="@dimen/small_margin" android:paddingStart="@dimen/normal_margin" android:paddingEnd="@dimen/activity_margin"> @@ -88,7 +88,7 @@ android:checked="true" android:clickable="false" android:layoutDirection="rtl" - android:padding="@dimen/medium_margin" + android:paddingHorizontal="@dimen/medium_margin" android:text="@string/export_tasks" /> @@ -106,7 +106,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:background="?attr/selectableItemBackground" - android:paddingVertical="@dimen/medium_margin" + android:paddingVertical="@dimen/small_margin" android:paddingStart="@dimen/normal_margin" android:paddingEnd="@dimen/activity_margin"> @@ -117,7 +117,7 @@ android:background="@null" android:clickable="false" android:layoutDirection="rtl" - android:padding="@dimen/medium_margin" + android:paddingHorizontal="@dimen/medium_margin" android:text="@string/export_past_entries" /> From 908241cb63f8618638f893f3bd38e5610be05a6a Mon Sep 17 00:00:00 2001 From: Naveen Date: Sun, 15 Jan 2023 19:17:21 +0530 Subject: [PATCH 09/12] Do not re-import tasks if they already exists! --- .../com/simplemobiletools/calendar/pro/helpers/IcsImporter.kt | 2 +- .../simplemobiletools/calendar/pro/interfaces/EventsDao.kt | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/helpers/IcsImporter.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/helpers/IcsImporter.kt index 09079be28..4af4311e6 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/helpers/IcsImporter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/helpers/IcsImporter.kt @@ -67,7 +67,7 @@ class IcsImporter(val activity: SimpleActivity) { ): ImportResult { try { val eventTypes = eventsHelper.getEventTypesSync() - val existingEvents = activity.eventsDB.getEventsWithImportIds().toMutableList() as ArrayList + val existingEvents = activity.eventsDB.getEventsOrTasksWithImportIds().toMutableList() as ArrayList val eventsToInsert = ArrayList() var line = "" diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/interfaces/EventsDao.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/interfaces/EventsDao.kt index 8bfdb6330..f88ede950 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/interfaces/EventsDao.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/interfaces/EventsDao.kt @@ -72,8 +72,8 @@ interface EventsDao { @Query("SELECT * FROM events WHERE source = \'$SOURCE_CONTACT_ANNIVERSARY\' AND type = $TYPE_EVENT") fun getAnniversaries(): List - @Query("SELECT * FROM events WHERE import_id != \"\" AND type = $TYPE_EVENT") - fun getEventsWithImportIds(): List + @Query("SELECT * FROM events WHERE import_id != \"\"") + fun getEventsOrTasksWithImportIds(): List @Query("SELECT * FROM events WHERE source = :source AND type = $TYPE_EVENT") fun getEventsFromCalDAVCalendar(source: String): List From f2ef7d79e237ab786e2a53353a756f20757eb9af Mon Sep 17 00:00:00 2001 From: Naveen Date: Sun, 15 Jan 2023 19:47:56 +0530 Subject: [PATCH 10/12] Add import IDs to existing tasks on start --- .../calendar/pro/activities/EventActivity.kt | 2 +- .../calendar/pro/activities/MainActivity.kt | 4 ++++ .../calendar/pro/activities/TaskActivity.kt | 2 +- .../calendar/pro/extensions/Context.kt | 21 +++++++++++++++++++ .../calendar/pro/helpers/Constants.kt | 5 +++++ .../calendar/pro/interfaces/EventsDao.kt | 6 ++++++ 6 files changed, 38 insertions(+), 2 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 869cf0e34..06fd98faa 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 @@ -1115,7 +1115,7 @@ class EventActivity : SimpleActivity() { val newImportId = if (mEvent.id != null) { mEvent.importId } else { - UUID.randomUUID().toString().replace("-", "") + System.currentTimeMillis().toString() + generateImportId() } val newEventType = if (!config.caldavSync || config.lastUsedCaldavCalendarId == 0 || mEventCalendarId == STORED_LOCALLY_ONLY) { 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 7277c01b7..20dd00e37 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 @@ -159,6 +159,10 @@ class MainActivity : SimpleActivity(), RefreshRecyclerViewListener { ConfirmationDialog(this, "", R.string.upgraded_to_pro_calendar, R.string.ok, 0, false) {} config.wasUpgradedFromFreeShown = true } + + addImportIdsToTasks { + refreshViewPager() + } } override fun onResume() { 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 ac37dc165..ed5a88269 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 @@ -354,7 +354,7 @@ class TaskActivity : SimpleActivity() { val newImportId = if (mTask.id != null) { mTask.importId } else { - UUID.randomUUID().toString().replace("-", "") + System.currentTimeMillis().toString() + generateImportId() } val reminders = getReminders() 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 c0e15a072..9135c0211 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 @@ -708,3 +708,24 @@ inline fun Context.queryCursorInlined( } } } + +fun Context.addImportIdsToTasks(callback: () -> Unit) { + ensureBackgroundThread { + var count = 0 + + eventsDB.getAllTasks() + .forEach { task -> + if (task.importId.isEmpty()) { + eventsDB.updateTaskImportId( + importId = generateImportId(), + id = task.id!! + ) + count += 1 + } + } + + if (count > 0) { + callback() + } + } +} 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 a81f5b7ed..4bb1a5019 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 @@ -3,6 +3,7 @@ package com.simplemobiletools.calendar.pro.helpers import com.simplemobiletools.calendar.pro.activities.EventActivity import com.simplemobiletools.calendar.pro.activities.TaskActivity import com.simplemobiletools.commons.helpers.MONTH_SECONDS +import java.util.* const val STORED_LOCALLY_ONLY = 0 const val ROW_COUNT = 6 @@ -258,3 +259,7 @@ fun getActivityToOpen(isTask: Boolean) = if (isTask) { } else { EventActivity::class.java } + +fun generateImportId(): String { + return UUID.randomUUID().toString().replace("-", "") + System.currentTimeMillis().toString() +} diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/interfaces/EventsDao.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/interfaces/EventsDao.kt index f88ede950..63ec3c9be 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/interfaces/EventsDao.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/interfaces/EventsDao.kt @@ -12,6 +12,9 @@ interface EventsDao { @Query("SELECT * FROM events") fun getAllEvents(): List + @Query("SELECT * FROM events WHERE type = $TYPE_TASK") + fun getAllTasks(): List + @Query("SELECT * FROM events WHERE event_type IN (:eventTypeIds) AND type = $TYPE_EVENT") fun getAllEventsWithTypes(eventTypeIds: List): List @@ -122,6 +125,9 @@ interface EventsDao { @Query("UPDATE events SET flags = :newFlags WHERE id = :id") fun updateTaskCompletion(id: Long, newFlags: Int) + @Query("UPDATE events SET import_id = :importId WHERE id = :id AND type = $TYPE_TASK") + fun updateTaskImportId(importId: String, id: Long) + @Insert(onConflict = OnConflictStrategy.REPLACE) fun insertOrUpdate(event: Event): Long From 0725eabcb229c835ccaee2eea65729c0d4f2509e Mon Sep 17 00:00:00 2001 From: Naveen Date: Sun, 15 Jan 2023 22:40:55 +0530 Subject: [PATCH 11/12] Use `smaller_margin` as padding --- app/src/main/res/layout/dialog_export_events.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/res/layout/dialog_export_events.xml b/app/src/main/res/layout/dialog_export_events.xml index 0949e17f2..96670c717 100644 --- a/app/src/main/res/layout/dialog_export_events.xml +++ b/app/src/main/res/layout/dialog_export_events.xml @@ -54,7 +54,7 @@ android:layout_height="wrap_content" android:layout_marginTop="@dimen/medium_margin" android:background="?attr/selectableItemBackground" - android:paddingVertical="@dimen/small_margin" + android:paddingVertical="@dimen/smaller_margin" android:paddingStart="@dimen/normal_margin" android:paddingEnd="@dimen/activity_margin"> @@ -76,7 +76,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:background="?attr/selectableItemBackground" - android:paddingVertical="@dimen/small_margin" + android:paddingVertical="@dimen/smaller_margin" android:paddingStart="@dimen/normal_margin" android:paddingEnd="@dimen/activity_margin"> @@ -106,7 +106,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:background="?attr/selectableItemBackground" - android:paddingVertical="@dimen/small_margin" + android:paddingVertical="@dimen/smaller_margin" android:paddingStart="@dimen/normal_margin" android:paddingEnd="@dimen/activity_margin"> From 54d0138b39eda93552d13b77a0e89f25c6c63bea Mon Sep 17 00:00:00 2001 From: Tibor Kaputa Date: Sun, 15 Jan 2023 20:32:10 +0100 Subject: [PATCH 12/12] Update Context.kt --- .../calendar/pro/extensions/Context.kt | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) 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 9135c0211..36538d89f 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 @@ -713,16 +713,15 @@ fun Context.addImportIdsToTasks(callback: () -> Unit) { ensureBackgroundThread { var count = 0 - eventsDB.getAllTasks() - .forEach { task -> - if (task.importId.isEmpty()) { - eventsDB.updateTaskImportId( - importId = generateImportId(), - id = task.id!! - ) - count += 1 - } + eventsDB.getAllTasks().forEach { task -> + if (task.importId.isEmpty()) { + eventsDB.updateTaskImportId( + importId = generateImportId(), + id = task.id!! + ) + count += 1 } + } if (count > 0) { callback()