Merge pull request #1785 from Naveen3Singh/repeating_tasks
Add task repetition
This commit is contained in:
commit
492c5ce621
|
@ -77,6 +77,7 @@ class EventActivity : SimpleActivity() {
|
|||
private var mOriginalTimeZone = DateTimeZone.getDefault().id
|
||||
private var mOriginalStartTS = 0L
|
||||
private var mOriginalEndTS = 0L
|
||||
private var mIsNewEvent = true
|
||||
|
||||
private lateinit var mEventStartDateTime: DateTime
|
||||
private lateinit var mEventEndDateTime: DateTime
|
||||
|
@ -353,6 +354,9 @@ class EventActivity : SimpleActivity() {
|
|||
|
||||
putLong(EVENT_TYPE_ID, mEventTypeId)
|
||||
putInt(EVENT_CALENDAR_ID, mEventCalendarId)
|
||||
putBoolean(IS_NEW_EVENT, mIsNewEvent)
|
||||
putLong(ORIGINAL_START_TS, mOriginalStartTS)
|
||||
putLong(ORIGINAL_END_TS, mOriginalEndTS)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -389,6 +393,9 @@ class EventActivity : SimpleActivity() {
|
|||
|
||||
mEventTypeId = getLong(EVENT_TYPE_ID)
|
||||
mEventCalendarId = getInt(EVENT_CALENDAR_ID)
|
||||
mIsNewEvent = getBoolean(IS_NEW_EVENT)
|
||||
mOriginalStartTS = getLong(ORIGINAL_START_TS)
|
||||
mOriginalEndTS = getLong(ORIGINAL_END_TS)
|
||||
}
|
||||
|
||||
checkRepeatTexts(mRepeatInterval)
|
||||
|
@ -397,6 +404,7 @@ class EventActivity : SimpleActivity() {
|
|||
updateEventType()
|
||||
updateCalDAVCalendar()
|
||||
checkAttendees()
|
||||
updateActionBarTitle()
|
||||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, resultData: Intent?) {
|
||||
|
@ -420,6 +428,7 @@ class EventActivity : SimpleActivity() {
|
|||
}
|
||||
|
||||
private fun setupEditEvent() {
|
||||
mIsNewEvent = false
|
||||
val realStart = if (mEventOccurrenceTS == 0L) mEvent.startTS else mEventOccurrenceTS
|
||||
val duration = mEvent.endTS - mEvent.startTS
|
||||
mOriginalStartTS = realStart
|
||||
|
@ -1105,15 +1114,15 @@ class EventActivity : SimpleActivity() {
|
|||
|
||||
val reminders = getReminders()
|
||||
if (!event_all_day.isChecked) {
|
||||
if (reminders.getOrNull(2)?.minutes ?: 0 < -1) {
|
||||
if ((reminders.getOrNull(2)?.minutes ?: 0) < -1) {
|
||||
reminders.removeAt(2)
|
||||
}
|
||||
|
||||
if (reminders.getOrNull(1)?.minutes ?: 0 < -1) {
|
||||
if ((reminders.getOrNull(1)?.minutes ?: 0) < -1) {
|
||||
reminders.removeAt(1)
|
||||
}
|
||||
|
||||
if (reminders.getOrNull(0)?.minutes ?: 0 < -1) {
|
||||
if ((reminders.getOrNull(0)?.minutes ?: 0) < -1) {
|
||||
reminders.removeAt(0)
|
||||
}
|
||||
}
|
||||
|
@ -1701,4 +1710,12 @@ class EventActivity : SimpleActivity() {
|
|||
it.applyColorFilter(textColor)
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateActionBarTitle() {
|
||||
if (mIsNewEvent) {
|
||||
updateActionBarTitle(getString(R.string.new_event))
|
||||
} else {
|
||||
updateActionBarTitle(getString(R.string.edit_event))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,25 +11,28 @@ import android.view.WindowManager
|
|||
import androidx.core.app.NotificationManagerCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.simplemobiletools.calendar.pro.R
|
||||
import com.simplemobiletools.calendar.pro.dialogs.ReminderWarningDialog
|
||||
import com.simplemobiletools.calendar.pro.dialogs.SelectEventTypeDialog
|
||||
import com.simplemobiletools.calendar.pro.dialogs.*
|
||||
import com.simplemobiletools.calendar.pro.extensions.*
|
||||
import com.simplemobiletools.calendar.pro.helpers.*
|
||||
import com.simplemobiletools.calendar.pro.helpers.Formatter
|
||||
import com.simplemobiletools.calendar.pro.models.Event
|
||||
import com.simplemobiletools.calendar.pro.models.EventType
|
||||
import com.simplemobiletools.calendar.pro.models.Reminder
|
||||
import com.simplemobiletools.commons.dialogs.ConfirmationAdvancedDialog
|
||||
import com.simplemobiletools.commons.dialogs.ConfirmationDialog
|
||||
import com.simplemobiletools.commons.dialogs.RadioGroupDialog
|
||||
import com.simplemobiletools.commons.extensions.*
|
||||
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
|
||||
import com.simplemobiletools.commons.helpers.*
|
||||
import com.simplemobiletools.commons.models.RadioItem
|
||||
import kotlinx.android.synthetic.main.activity_task.*
|
||||
import org.joda.time.DateTime
|
||||
import java.util.*
|
||||
import kotlin.math.pow
|
||||
|
||||
class TaskActivity : SimpleActivity() {
|
||||
private var mEventTypeId = REGULAR_EVENT_TYPE_ID
|
||||
private lateinit var mTaskDateTime: DateTime
|
||||
private lateinit var mTask: Event
|
||||
private var mIsAllDayEvent = false
|
||||
|
||||
private var mReminder1Minutes = REMINDER_OFF
|
||||
private var mReminder2Minutes = REMINDER_OFF
|
||||
|
@ -37,6 +40,14 @@ class TaskActivity : SimpleActivity() {
|
|||
private var mReminder1Type = REMINDER_NOTIFICATION
|
||||
private var mReminder2Type = REMINDER_NOTIFICATION
|
||||
private var mReminder3Type = REMINDER_NOTIFICATION
|
||||
private var mRepeatInterval = 0
|
||||
private var mRepeatLimit = 0L
|
||||
private var mRepeatRule = 0
|
||||
private var mTaskOccurrenceTS = 0L
|
||||
private var mOriginalStartTS = 0L
|
||||
private var mTaskCompleted = false
|
||||
private var mLastSavePromptTS = 0L
|
||||
private var mIsNewTask = true
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
@ -57,9 +68,11 @@ class TaskActivity : SimpleActivity() {
|
|||
return@ensureBackgroundThread
|
||||
}
|
||||
|
||||
val storedEventTypes = eventTypesDB.getEventTypes().toMutableList() as ArrayList<EventType>
|
||||
val localEventType = storedEventTypes.firstOrNull { it.id == config.lastUsedLocalEventTypeId }
|
||||
runOnUiThread {
|
||||
if (!isDestroyed && !isFinishing) {
|
||||
gotTask(savedInstanceState, task)
|
||||
gotTask(savedInstanceState, localEventType, task)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -78,7 +91,7 @@ class TaskActivity : SimpleActivity() {
|
|||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
when (item.itemId) {
|
||||
R.id.save -> saveTask()
|
||||
R.id.save -> saveCurrentTask()
|
||||
R.id.delete -> deleteTask()
|
||||
R.id.duplicate -> duplicateTask()
|
||||
else -> return super.onOptionsItemSelected(item)
|
||||
|
@ -86,6 +99,49 @@ class TaskActivity : SimpleActivity() {
|
|||
return true
|
||||
}
|
||||
|
||||
private fun isTaskChanged(): Boolean {
|
||||
if (!this::mTask.isInitialized) {
|
||||
return false
|
||||
}
|
||||
|
||||
val newStartTS: Long = mTaskDateTime.seconds()
|
||||
val hasTimeChanged = if (mOriginalStartTS == 0L) {
|
||||
mTask.startTS != newStartTS
|
||||
} else {
|
||||
mOriginalStartTS != newStartTS
|
||||
}
|
||||
|
||||
val reminders = getReminders()
|
||||
val originalReminders = mTask.getReminders()
|
||||
if (task_title.text.toString() != mTask.title ||
|
||||
task_description.text.toString() != mTask.description ||
|
||||
reminders != originalReminders ||
|
||||
mRepeatInterval != mTask.repeatInterval ||
|
||||
mRepeatRule != mTask.repeatRule ||
|
||||
mEventTypeId != mTask.eventType ||
|
||||
hasTimeChanged
|
||||
) {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
override fun onBackPressed() {
|
||||
if (System.currentTimeMillis() - mLastSavePromptTS > SAVE_DISCARD_PROMPT_INTERVAL && isTaskChanged()) {
|
||||
mLastSavePromptTS = System.currentTimeMillis()
|
||||
ConfirmationAdvancedDialog(this, "", R.string.save_before_closing, R.string.save, R.string.discard) {
|
||||
if (it) {
|
||||
saveCurrentTask()
|
||||
} else {
|
||||
super.onBackPressed()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
super.onBackPressed()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
if (!::mTask.isInitialized) {
|
||||
|
@ -100,6 +156,14 @@ class TaskActivity : SimpleActivity() {
|
|||
putInt(REMINDER_1_MINUTES, mReminder1Minutes)
|
||||
putInt(REMINDER_2_MINUTES, mReminder2Minutes)
|
||||
putInt(REMINDER_3_MINUTES, mReminder3Minutes)
|
||||
|
||||
putInt(REPEAT_INTERVAL, mRepeatInterval)
|
||||
putInt(REPEAT_RULE, mRepeatRule)
|
||||
putLong(REPEAT_LIMIT, mRepeatLimit)
|
||||
|
||||
putLong(EVENT_TYPE_ID, mEventTypeId)
|
||||
putBoolean(IS_NEW_EVENT, mIsNewTask)
|
||||
putLong(ORIGINAL_START_TS, mOriginalStartTS)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -119,19 +183,34 @@ class TaskActivity : SimpleActivity() {
|
|||
mReminder1Minutes = getInt(REMINDER_1_MINUTES)
|
||||
mReminder2Minutes = getInt(REMINDER_2_MINUTES)
|
||||
mReminder3Minutes = getInt(REMINDER_3_MINUTES)
|
||||
|
||||
mRepeatInterval = getInt(REPEAT_INTERVAL)
|
||||
mRepeatRule = getInt(REPEAT_RULE)
|
||||
mRepeatLimit = getLong(REPEAT_LIMIT)
|
||||
mEventTypeId = getLong(EVENT_TYPE_ID)
|
||||
mIsNewTask = getBoolean(IS_NEW_EVENT)
|
||||
mOriginalStartTS = getLong(ORIGINAL_START_TS)
|
||||
}
|
||||
|
||||
updateEventType()
|
||||
updateDateText()
|
||||
updateTimeText()
|
||||
updateTexts()
|
||||
setupMarkCompleteButton()
|
||||
checkRepeatTexts(mRepeatInterval)
|
||||
checkRepeatRule()
|
||||
updateActionBarTitle()
|
||||
}
|
||||
|
||||
private fun gotTask(savedInstanceState: Bundle?, task: Event?) {
|
||||
private fun gotTask(savedInstanceState: Bundle?, localEventType: EventType?, task: Event?) {
|
||||
if (localEventType == null) {
|
||||
config.lastUsedLocalEventTypeId = REGULAR_EVENT_TYPE_ID
|
||||
}
|
||||
|
||||
mEventTypeId = if (config.defaultEventTypeId == -1L) config.lastUsedLocalEventTypeId else config.defaultEventTypeId
|
||||
|
||||
if (task != null) {
|
||||
mTask = task
|
||||
|
||||
mTaskOccurrenceTS = intent.getLongExtra(EVENT_OCCURRENCE_TS, 0L)
|
||||
mTaskCompleted = intent.getBooleanExtra(IS_TASK_COMPLETED, false)
|
||||
if (intent.getBooleanExtra(IS_DUPLICATE_INTENT, false)) {
|
||||
mTask.id = null
|
||||
updateActionBarTitle(getString(R.string.new_task))
|
||||
|
@ -160,9 +239,12 @@ class TaskActivity : SimpleActivity() {
|
|||
|
||||
task_date.setOnClickListener { setupDate() }
|
||||
task_time.setOnClickListener { setupTime() }
|
||||
event_type_holder.setOnClickListener { showEventTypeDialog() }
|
||||
task_type_holder.setOnClickListener { showEventTypeDialog() }
|
||||
task_repetition.setOnClickListener { showRepeatIntervalDialog() }
|
||||
task_repetition_rule_holder.setOnClickListener { showRepetitionRuleDialog() }
|
||||
task_repetition_limit_holder.setOnClickListener { showRepetitionTypePicker() }
|
||||
|
||||
event_reminder_1.setOnClickListener {
|
||||
task_reminder_1.setOnClickListener {
|
||||
handleNotificationAvailability {
|
||||
if (config.wasAlarmWarningShown) {
|
||||
showReminder1Dialog()
|
||||
|
@ -175,19 +257,20 @@ class TaskActivity : SimpleActivity() {
|
|||
}
|
||||
}
|
||||
|
||||
event_reminder_2.setOnClickListener { showReminder2Dialog() }
|
||||
event_reminder_3.setOnClickListener { showReminder3Dialog() }
|
||||
task_reminder_2.setOnClickListener { showReminder2Dialog() }
|
||||
task_reminder_3.setOnClickListener { showReminder3Dialog() }
|
||||
|
||||
if (savedInstanceState == null) {
|
||||
updateEventType()
|
||||
updateDateText()
|
||||
updateTimeText()
|
||||
updateReminderTexts()
|
||||
updateTexts()
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupEditTask() {
|
||||
mTaskDateTime = Formatter.getDateTimeFromTS(mTask.startTS)
|
||||
mIsNewTask = false
|
||||
val realStart = if (mTaskOccurrenceTS == 0L) mTask.startTS else mTaskOccurrenceTS
|
||||
mOriginalStartTS = realStart
|
||||
mTaskDateTime = Formatter.getDateTimeFromTS(realStart)
|
||||
window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN)
|
||||
updateActionBarTitle(getString(R.string.edit_task))
|
||||
|
||||
|
@ -198,12 +281,16 @@ class TaskActivity : SimpleActivity() {
|
|||
mReminder1Type = mTask.reminder1Type
|
||||
mReminder2Type = mTask.reminder2Type
|
||||
mReminder3Type = mTask.reminder3Type
|
||||
mRepeatInterval = mTask.repeatInterval
|
||||
mRepeatLimit = mTask.repeatLimit
|
||||
mRepeatRule = mTask.repeatRule
|
||||
|
||||
task_title.setText(mTask.title)
|
||||
task_description.setText(mTask.description)
|
||||
task_all_day.isChecked = mTask.getIsAllDay()
|
||||
toggleAllDay(mTask.getIsAllDay())
|
||||
setupMarkCompleteButton()
|
||||
checkRepeatTexts(mRepeatInterval)
|
||||
}
|
||||
|
||||
private fun setupNewTask() {
|
||||
|
@ -214,6 +301,33 @@ class TaskActivity : SimpleActivity() {
|
|||
window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE)
|
||||
task_title.requestFocus()
|
||||
updateActionBarTitle(getString(R.string.new_task))
|
||||
|
||||
mTask.apply {
|
||||
this.startTS = mTaskDateTime.seconds()
|
||||
this.endTS = mTaskDateTime.seconds()
|
||||
reminder1Minutes = mReminder1Minutes
|
||||
reminder1Type = mReminder1Type
|
||||
reminder2Minutes = mReminder2Minutes
|
||||
reminder2Type = mReminder2Type
|
||||
reminder3Minutes = mReminder3Minutes
|
||||
reminder3Type = mReminder3Type
|
||||
eventType = mEventTypeId
|
||||
}
|
||||
}
|
||||
|
||||
private fun saveCurrentTask() {
|
||||
if (config.wasAlarmWarningShown || (mReminder1Minutes == REMINDER_OFF && mReminder2Minutes == REMINDER_OFF && mReminder3Minutes == REMINDER_OFF)) {
|
||||
ensureBackgroundThread {
|
||||
saveTask()
|
||||
}
|
||||
} else {
|
||||
ReminderWarningDialog(this) {
|
||||
config.wasAlarmWarningShown = true
|
||||
ensureBackgroundThread {
|
||||
saveTask()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun saveTask() {
|
||||
|
@ -226,6 +340,7 @@ class TaskActivity : SimpleActivity() {
|
|||
return
|
||||
}
|
||||
|
||||
val wasRepeatable = mTask.repeatInterval > 0
|
||||
|
||||
val reminders = getReminders()
|
||||
if (!task_all_day.isChecked) {
|
||||
|
@ -260,21 +375,37 @@ class TaskActivity : SimpleActivity() {
|
|||
endTS = startTS
|
||||
title = newTitle
|
||||
description = task_description.value
|
||||
|
||||
// migrate completed task to the new completed tasks db
|
||||
if (!wasRepeatable && mTask.isTaskCompleted()) {
|
||||
mTask.flags = mTask.flags.removeBit(FLAG_TASK_COMPLETED)
|
||||
ensureBackgroundThread {
|
||||
updateTaskCompletion(copy(startTS = mOriginalStartTS), true)
|
||||
}
|
||||
}
|
||||
flags = mTask.flags.addBitIf(task_all_day.isChecked, FLAG_ALL_DAY)
|
||||
lastUpdated = System.currentTimeMillis()
|
||||
eventType = mEventTypeId
|
||||
type = TYPE_TASK
|
||||
|
||||
reminder1Minutes = mReminder1Minutes
|
||||
reminder1Minutes = reminder1.minutes
|
||||
reminder1Type = mReminder1Type
|
||||
reminder2Minutes = mReminder2Minutes
|
||||
reminder2Minutes = reminder2.minutes
|
||||
reminder2Type = mReminder2Type
|
||||
reminder3Minutes = mReminder3Minutes
|
||||
reminder3Minutes = reminder3.minutes
|
||||
reminder3Type = mReminder3Type
|
||||
|
||||
repeatInterval = mRepeatInterval
|
||||
repeatLimit = if (repeatInterval == 0) 0 else mRepeatLimit
|
||||
repeatRule = mRepeatRule
|
||||
}
|
||||
|
||||
ensureBackgroundThread {
|
||||
EventsHelper(this).insertTask(mTask, true) {
|
||||
storeTask(wasRepeatable)
|
||||
}
|
||||
|
||||
private fun storeTask(wasRepeatable: Boolean) {
|
||||
if (mTask.id == null) {
|
||||
eventsHelper.insertTask(mTask, true) {
|
||||
hideKeyboard()
|
||||
|
||||
if (DateTime.now().isAfter(mTaskDateTime.millis)) {
|
||||
|
@ -285,13 +416,76 @@ class TaskActivity : SimpleActivity() {
|
|||
|
||||
finish()
|
||||
}
|
||||
} else {
|
||||
if (mRepeatInterval > 0 && wasRepeatable) {
|
||||
runOnUiThread {
|
||||
showEditRepeatingTaskDialog()
|
||||
}
|
||||
} else {
|
||||
hideKeyboard()
|
||||
eventsHelper.updateEvent(mTask, updateAtCalDAV = false, showToasts = true) {
|
||||
finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun showEditRepeatingTaskDialog() {
|
||||
EditRepeatingEventDialog(this, isTask = true) {
|
||||
hideKeyboard()
|
||||
when (it) {
|
||||
0 -> {
|
||||
ensureBackgroundThread {
|
||||
eventsHelper.addEventRepetitionException(mTask.id!!, mTaskOccurrenceTS, true)
|
||||
mTask.apply {
|
||||
parentId = id!!.toLong()
|
||||
id = null
|
||||
repeatRule = 0
|
||||
repeatInterval = 0
|
||||
repeatLimit = 0
|
||||
}
|
||||
|
||||
eventsHelper.insertTask(mTask, showToasts = true) {
|
||||
finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
1 -> {
|
||||
ensureBackgroundThread {
|
||||
eventsHelper.addEventRepeatLimit(mTask.id!!, mTaskOccurrenceTS)
|
||||
mTask.apply {
|
||||
id = null
|
||||
}
|
||||
|
||||
eventsHelper.insertTask(mTask, showToasts = true) {
|
||||
finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
2 -> {
|
||||
ensureBackgroundThread {
|
||||
eventsHelper.addEventRepeatLimit(mTask.id!!, mTaskOccurrenceTS)
|
||||
eventsHelper.updateEvent(mTask, updateAtCalDAV = false, showToasts = true) {
|
||||
finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun deleteTask() {
|
||||
ConfirmationDialog(this) {
|
||||
if (mTask.id == null) {
|
||||
return
|
||||
}
|
||||
|
||||
DeleteEventDialog(this, arrayListOf(mTask.id!!), mTask.repeatInterval > 0, isTask = true) {
|
||||
ensureBackgroundThread {
|
||||
eventsHelper.deleteEvent(mTask.id!!, false)
|
||||
when (it) {
|
||||
DELETE_SELECTED_OCCURRENCE -> eventsHelper.addEventRepetitionException(mTask.id!!, mTaskOccurrenceTS, true)
|
||||
DELETE_FUTURE_OCCURRENCES -> eventsHelper.addEventRepeatLimit(mTask.id!!, mTaskOccurrenceTS)
|
||||
DELETE_ALL_OCCURRENCES -> eventsHelper.deleteEvent(mTask.id!!, true)
|
||||
}
|
||||
|
||||
runOnUiThread {
|
||||
hideKeyboard()
|
||||
|
@ -340,6 +534,7 @@ class TaskActivity : SimpleActivity() {
|
|||
private fun dateSet(year: Int, month: Int, day: Int) {
|
||||
mTaskDateTime = mTaskDateTime.withDate(year, month + 1, day)
|
||||
updateDateText()
|
||||
checkRepeatRule()
|
||||
}
|
||||
|
||||
private fun timeSet(hours: Int, minutes: Int) {
|
||||
|
@ -347,6 +542,28 @@ class TaskActivity : SimpleActivity() {
|
|||
updateTimeText()
|
||||
}
|
||||
|
||||
private fun updateTexts() {
|
||||
updateDateText()
|
||||
updateTimeText()
|
||||
updateReminderTexts()
|
||||
updateRepetitionText()
|
||||
}
|
||||
|
||||
private fun checkRepeatRule() {
|
||||
if (mRepeatInterval.isXWeeklyRepetition()) {
|
||||
val day = mRepeatRule
|
||||
if (day == MONDAY_BIT || day == TUESDAY_BIT || day == WEDNESDAY_BIT || day == THURSDAY_BIT || day == FRIDAY_BIT || day == SATURDAY_BIT || day == SUNDAY_BIT) {
|
||||
setRepeatRule(2.0.pow((mTaskDateTime.dayOfWeek - 1).toDouble()).toInt())
|
||||
}
|
||||
} else if (mRepeatInterval.isXMonthlyRepetition() || mRepeatInterval.isXYearlyRepetition()) {
|
||||
if (mRepeatRule == REPEAT_LAST_DAY && !isLastDayOfTheMonth()) {
|
||||
mRepeatRule = REPEAT_SAME_DAY
|
||||
}
|
||||
checkRepetitionRuleText()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun updateDateText() {
|
||||
task_date.text = Formatter.getDate(this, mTaskDateTime)
|
||||
}
|
||||
|
@ -363,7 +580,18 @@ class TaskActivity : SimpleActivity() {
|
|||
private fun setupMarkCompleteButton() {
|
||||
toggle_mark_complete.setOnClickListener { toggleCompletion() }
|
||||
toggle_mark_complete.beVisibleIf(mTask.id != null)
|
||||
if (mTask.isTaskCompleted()) {
|
||||
updateTaskCompletedButton()
|
||||
ensureBackgroundThread {
|
||||
// the stored value might be incorrect so update it (e.g. user completed the task via notification action before editing)
|
||||
mTaskCompleted = isTaskCompleted(mTask.copy(startTS = mOriginalStartTS))
|
||||
runOnUiThread {
|
||||
updateTaskCompletedButton()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateTaskCompletedButton() {
|
||||
if (mTaskCompleted) {
|
||||
toggle_mark_complete.background = ContextCompat.getDrawable(this, R.drawable.button_background_stroke)
|
||||
toggle_mark_complete.setText(R.string.mark_incomplete)
|
||||
toggle_mark_complete.setTextColor(getProperTextColor())
|
||||
|
@ -378,14 +606,9 @@ class TaskActivity : SimpleActivity() {
|
|||
}
|
||||
|
||||
private fun toggleCompletion() {
|
||||
if (mTask.isTaskCompleted()) {
|
||||
mTask.flags = mTask.flags.removeBit(FLAG_TASK_COMPLETED)
|
||||
} else {
|
||||
mTask.flags = mTask.flags or FLAG_TASK_COMPLETED
|
||||
}
|
||||
|
||||
ensureBackgroundThread {
|
||||
eventsDB.updateTaskCompletion(mTask.id!!, mTask.flags)
|
||||
val task = mTask.copy(startTS = mOriginalStartTS)
|
||||
updateTaskCompletion(task, completed = !mTaskCompleted)
|
||||
hideKeyboard()
|
||||
finish()
|
||||
}
|
||||
|
@ -398,12 +621,12 @@ class TaskActivity : SimpleActivity() {
|
|||
}
|
||||
|
||||
private fun updateReminder1Text() {
|
||||
event_reminder_1.text = getFormattedMinutes(mReminder1Minutes)
|
||||
task_reminder_1.text = getFormattedMinutes(mReminder1Minutes)
|
||||
}
|
||||
|
||||
private fun updateReminder2Text() {
|
||||
event_reminder_2.apply {
|
||||
beGoneIf(event_reminder_2.isGone() && mReminder1Minutes == REMINDER_OFF)
|
||||
task_reminder_2.apply {
|
||||
beGoneIf(task_reminder_2.isGone() && mReminder1Minutes == REMINDER_OFF)
|
||||
if (mReminder2Minutes == REMINDER_OFF) {
|
||||
text = resources.getString(R.string.add_another_reminder)
|
||||
alpha = 0.4f
|
||||
|
@ -415,8 +638,8 @@ class TaskActivity : SimpleActivity() {
|
|||
}
|
||||
|
||||
private fun updateReminder3Text() {
|
||||
event_reminder_3.apply {
|
||||
beGoneIf(event_reminder_3.isGone() && (mReminder2Minutes == REMINDER_OFF || mReminder1Minutes == REMINDER_OFF))
|
||||
task_reminder_3.apply {
|
||||
beGoneIf(task_reminder_3.isGone() && (mReminder2Minutes == REMINDER_OFF || mReminder1Minutes == REMINDER_OFF))
|
||||
if (mReminder3Minutes == REMINDER_OFF) {
|
||||
text = resources.getString(R.string.add_another_reminder)
|
||||
alpha = 0.4f
|
||||
|
@ -438,21 +661,21 @@ class TaskActivity : SimpleActivity() {
|
|||
}
|
||||
|
||||
private fun showReminder1Dialog() {
|
||||
showPickSecondsDialogHelper(mReminder1Minutes, showDuringDayOption = mIsAllDayEvent) {
|
||||
showPickSecondsDialogHelper(mReminder1Minutes) {
|
||||
mReminder1Minutes = if (it == -1 || it == 0) it else it / 60
|
||||
updateReminderTexts()
|
||||
}
|
||||
}
|
||||
|
||||
private fun showReminder2Dialog() {
|
||||
showPickSecondsDialogHelper(mReminder2Minutes, showDuringDayOption = mIsAllDayEvent) {
|
||||
showPickSecondsDialogHelper(mReminder2Minutes) {
|
||||
mReminder2Minutes = if (it == -1 || it == 0) it else it / 60
|
||||
updateReminderTexts()
|
||||
}
|
||||
}
|
||||
|
||||
private fun showReminder3Dialog() {
|
||||
showPickSecondsDialogHelper(mReminder3Minutes, showDuringDayOption = mIsAllDayEvent) {
|
||||
showPickSecondsDialogHelper(mReminder3Minutes) {
|
||||
mReminder3Minutes = if (it == -1 || it == 0) it else it / 60
|
||||
updateReminderTexts()
|
||||
}
|
||||
|
@ -488,8 +711,8 @@ class TaskActivity : SimpleActivity() {
|
|||
val eventType = eventTypesDB.getEventTypeWithId(mEventTypeId)
|
||||
if (eventType != null) {
|
||||
runOnUiThread {
|
||||
event_type.text = eventType.title
|
||||
event_type_color.setFillWithStroke(eventType.color, getProperBackgroundColor())
|
||||
task_type.text = eventType.title
|
||||
task_type_color.setFillWithStroke(eventType.color, getProperBackgroundColor())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -499,9 +722,234 @@ class TaskActivity : SimpleActivity() {
|
|||
updateTextColors(task_scrollview)
|
||||
val textColor = getProperTextColor()
|
||||
arrayOf(
|
||||
task_time_image, event_reminder_image, event_type_image
|
||||
task_time_image, task_reminder_image, task_type_image
|
||||
).forEach {
|
||||
it.applyColorFilter(textColor)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun showRepeatIntervalDialog() {
|
||||
showEventRepeatIntervalDialog(mRepeatInterval) {
|
||||
setRepeatInterval(it)
|
||||
}
|
||||
}
|
||||
|
||||
private fun setRepeatInterval(interval: Int) {
|
||||
mRepeatInterval = interval
|
||||
updateRepetitionText()
|
||||
checkRepeatTexts(interval)
|
||||
|
||||
when {
|
||||
mRepeatInterval.isXWeeklyRepetition() -> setRepeatRule(2.0.pow((mTaskDateTime.dayOfWeek - 1).toDouble()).toInt())
|
||||
mRepeatInterval.isXMonthlyRepetition() -> setRepeatRule(REPEAT_SAME_DAY)
|
||||
mRepeatInterval.isXYearlyRepetition() -> setRepeatRule(REPEAT_SAME_DAY)
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkRepeatTexts(limit: Int) {
|
||||
task_repetition_limit_holder.beGoneIf(limit == 0)
|
||||
checkRepetitionLimitText()
|
||||
|
||||
task_repetition_rule_holder.beVisibleIf(mRepeatInterval.isXWeeklyRepetition() || mRepeatInterval.isXMonthlyRepetition() || mRepeatInterval.isXYearlyRepetition())
|
||||
checkRepetitionRuleText()
|
||||
}
|
||||
|
||||
private fun showRepetitionTypePicker() {
|
||||
hideKeyboard()
|
||||
RepeatLimitTypePickerDialog(this, mRepeatLimit, mTaskDateTime.seconds()) {
|
||||
setRepeatLimit(it)
|
||||
}
|
||||
}
|
||||
|
||||
private fun setRepeatLimit(limit: Long) {
|
||||
mRepeatLimit = limit
|
||||
checkRepetitionLimitText()
|
||||
}
|
||||
|
||||
private fun checkRepetitionLimitText() {
|
||||
task_repetition_limit.text = when {
|
||||
mRepeatLimit == 0L -> {
|
||||
task_repetition_limit_label.text = getString(R.string.repeat)
|
||||
resources.getString(R.string.forever)
|
||||
}
|
||||
mRepeatLimit > 0 -> {
|
||||
task_repetition_limit_label.text = getString(R.string.repeat_till)
|
||||
val repeatLimitDateTime = Formatter.getDateTimeFromTS(mRepeatLimit)
|
||||
Formatter.getFullDate(this, repeatLimitDateTime)
|
||||
}
|
||||
else -> {
|
||||
task_repetition_limit_label.text = getString(R.string.repeat)
|
||||
"${-mRepeatLimit} ${getString(R.string.times)}"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun showRepetitionRuleDialog() {
|
||||
hideKeyboard()
|
||||
when {
|
||||
mRepeatInterval.isXWeeklyRepetition() -> RepeatRuleWeeklyDialog(this, mRepeatRule) {
|
||||
setRepeatRule(it)
|
||||
}
|
||||
mRepeatInterval.isXMonthlyRepetition() -> {
|
||||
val items = getAvailableMonthlyRepetitionRules()
|
||||
RadioGroupDialog(this, items, mRepeatRule) {
|
||||
setRepeatRule(it as Int)
|
||||
}
|
||||
}
|
||||
mRepeatInterval.isXYearlyRepetition() -> {
|
||||
val items = getAvailableYearlyRepetitionRules()
|
||||
RadioGroupDialog(this, items, mRepeatRule) {
|
||||
setRepeatRule(it as Int)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getAvailableMonthlyRepetitionRules(): ArrayList<RadioItem> {
|
||||
val items = arrayListOf(RadioItem(REPEAT_SAME_DAY, getString(R.string.repeat_on_the_same_day_monthly)))
|
||||
|
||||
items.add(RadioItem(REPEAT_ORDER_WEEKDAY, getRepeatXthDayString(true, REPEAT_ORDER_WEEKDAY)))
|
||||
if (isLastWeekDayOfMonth()) {
|
||||
items.add(RadioItem(REPEAT_ORDER_WEEKDAY_USE_LAST, getRepeatXthDayString(true, REPEAT_ORDER_WEEKDAY_USE_LAST)))
|
||||
}
|
||||
|
||||
if (isLastDayOfTheMonth()) {
|
||||
items.add(RadioItem(REPEAT_LAST_DAY, getString(R.string.repeat_on_the_last_day_monthly)))
|
||||
}
|
||||
return items
|
||||
}
|
||||
|
||||
private fun getAvailableYearlyRepetitionRules(): ArrayList<RadioItem> {
|
||||
val items = arrayListOf(RadioItem(REPEAT_SAME_DAY, getString(R.string.repeat_on_the_same_day_yearly)))
|
||||
|
||||
items.add(RadioItem(REPEAT_ORDER_WEEKDAY, getRepeatXthDayInMonthString(true, REPEAT_ORDER_WEEKDAY)))
|
||||
if (isLastWeekDayOfMonth()) {
|
||||
items.add(RadioItem(REPEAT_ORDER_WEEKDAY_USE_LAST, getRepeatXthDayInMonthString(true, REPEAT_ORDER_WEEKDAY_USE_LAST)))
|
||||
}
|
||||
|
||||
return items
|
||||
}
|
||||
|
||||
private fun isLastDayOfTheMonth() = mTaskDateTime.dayOfMonth == mTaskDateTime.dayOfMonth().withMaximumValue().dayOfMonth
|
||||
|
||||
private fun isLastWeekDayOfMonth() = mTaskDateTime.monthOfYear != mTaskDateTime.plusDays(7).monthOfYear
|
||||
|
||||
private fun getRepeatXthDayString(includeBase: Boolean, repeatRule: Int): String {
|
||||
val dayOfWeek = mTaskDateTime.dayOfWeek
|
||||
val base = getBaseString(dayOfWeek)
|
||||
val order = getOrderString(repeatRule)
|
||||
val dayString = getDayString(dayOfWeek)
|
||||
return if (includeBase) {
|
||||
"$base $order $dayString"
|
||||
} else {
|
||||
val everyString = getString(if (isMaleGender(mTaskDateTime.dayOfWeek)) R.string.every_m else R.string.every_f)
|
||||
"$everyString $order $dayString"
|
||||
}
|
||||
}
|
||||
|
||||
private fun getBaseString(day: Int): String {
|
||||
return getString(
|
||||
if (isMaleGender(day)) {
|
||||
R.string.repeat_every_m
|
||||
} else {
|
||||
R.string.repeat_every_f
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
private fun isMaleGender(day: Int) = day == 1 || day == 2 || day == 4 || day == 5
|
||||
|
||||
private fun getOrderString(repeatRule: Int): String {
|
||||
val dayOfMonth = mTaskDateTime.dayOfMonth
|
||||
var order = (dayOfMonth - 1) / 7 + 1
|
||||
if (isLastWeekDayOfMonth() && repeatRule == REPEAT_ORDER_WEEKDAY_USE_LAST) {
|
||||
order = -1
|
||||
}
|
||||
|
||||
val isMale = isMaleGender(mTaskDateTime.dayOfWeek)
|
||||
return getString(
|
||||
when (order) {
|
||||
1 -> if (isMale) R.string.first_m else R.string.first_f
|
||||
2 -> if (isMale) R.string.second_m else R.string.second_f
|
||||
3 -> if (isMale) R.string.third_m else R.string.third_f
|
||||
4 -> if (isMale) R.string.fourth_m else R.string.fourth_f
|
||||
5 -> if (isMale) R.string.fifth_m else R.string.fifth_f
|
||||
else -> if (isMale) R.string.last_m else R.string.last_f
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
private fun getDayString(day: Int): String {
|
||||
return getString(
|
||||
when (day) {
|
||||
1 -> R.string.monday_alt
|
||||
2 -> R.string.tuesday_alt
|
||||
3 -> R.string.wednesday_alt
|
||||
4 -> R.string.thursday_alt
|
||||
5 -> R.string.friday_alt
|
||||
6 -> R.string.saturday_alt
|
||||
else -> R.string.sunday_alt
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
private fun getRepeatXthDayInMonthString(includeBase: Boolean, repeatRule: Int): String {
|
||||
val weekDayString = getRepeatXthDayString(includeBase, repeatRule)
|
||||
val monthString = resources.getStringArray(R.array.in_months)[mTaskDateTime.monthOfYear - 1]
|
||||
return "$weekDayString $monthString"
|
||||
}
|
||||
|
||||
private fun setRepeatRule(rule: Int) {
|
||||
mRepeatRule = rule
|
||||
checkRepetitionRuleText()
|
||||
if (rule == 0) {
|
||||
setRepeatInterval(0)
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkRepetitionRuleText() {
|
||||
when {
|
||||
mRepeatInterval.isXWeeklyRepetition() -> {
|
||||
task_repetition_rule.text = if (mRepeatRule == EVERY_DAY_BIT) getString(R.string.every_day) else getSelectedDaysString(mRepeatRule)
|
||||
}
|
||||
mRepeatInterval.isXMonthlyRepetition() -> {
|
||||
val repeatString = if (mRepeatRule == REPEAT_ORDER_WEEKDAY_USE_LAST || mRepeatRule == REPEAT_ORDER_WEEKDAY)
|
||||
R.string.repeat else R.string.repeat_on
|
||||
|
||||
task_repetition_rule_label.text = getString(repeatString)
|
||||
task_repetition_rule.text = getMonthlyRepetitionRuleText()
|
||||
}
|
||||
mRepeatInterval.isXYearlyRepetition() -> {
|
||||
val repeatString = if (mRepeatRule == REPEAT_ORDER_WEEKDAY_USE_LAST || mRepeatRule == REPEAT_ORDER_WEEKDAY)
|
||||
R.string.repeat else R.string.repeat_on
|
||||
|
||||
task_repetition_rule_label.text = getString(repeatString)
|
||||
task_repetition_rule.text = getYearlyRepetitionRuleText()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getMonthlyRepetitionRuleText() = when (mRepeatRule) {
|
||||
REPEAT_SAME_DAY -> getString(R.string.the_same_day)
|
||||
REPEAT_LAST_DAY -> getString(R.string.the_last_day)
|
||||
else -> getRepeatXthDayString(false, mRepeatRule)
|
||||
}
|
||||
|
||||
private fun getYearlyRepetitionRuleText() = when (mRepeatRule) {
|
||||
REPEAT_SAME_DAY -> getString(R.string.the_same_day)
|
||||
else -> getRepeatXthDayInMonthString(false, mRepeatRule)
|
||||
}
|
||||
|
||||
private fun updateRepetitionText() {
|
||||
task_repetition.text = getRepetitionText(mRepeatInterval)
|
||||
}
|
||||
|
||||
private fun updateActionBarTitle() {
|
||||
if (mIsNewTask) {
|
||||
updateActionBarTitle(getString(R.string.new_task))
|
||||
} else {
|
||||
updateActionBarTitle(getString(R.string.edit_task))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -191,27 +191,27 @@ class EventListWidgetAdapter(val context: Context, val intent: Intent) : RemoteV
|
|||
context.eventsHelper.getEventsSync(fromTS, toTS, applyTypeFilter = true) {
|
||||
val listItems = ArrayList<ListItem>(it.size)
|
||||
val replaceDescription = context.config.replaceDescription
|
||||
val sorted = it.sortedWith(compareBy<Event> {
|
||||
if (it.getIsAllDay()) {
|
||||
Formatter.getDayStartTS(Formatter.getDayCodeFromTS(it.startTS)) - 1
|
||||
val sorted = it.sortedWith(compareBy<Event> { event ->
|
||||
if (event.getIsAllDay()) {
|
||||
Formatter.getDayStartTS(Formatter.getDayCodeFromTS(event.startTS)) - 1
|
||||
} else {
|
||||
it.startTS
|
||||
event.startTS
|
||||
}
|
||||
}.thenBy {
|
||||
if (it.getIsAllDay()) {
|
||||
Formatter.getDayEndTS(Formatter.getDayCodeFromTS(it.endTS))
|
||||
}.thenBy { event ->
|
||||
if (event.getIsAllDay()) {
|
||||
Formatter.getDayEndTS(Formatter.getDayCodeFromTS(event.endTS))
|
||||
} else {
|
||||
it.endTS
|
||||
event.endTS
|
||||
}
|
||||
}.thenBy { it.title }.thenBy { if (replaceDescription) it.location else it.description })
|
||||
}.thenBy { event -> event.title }.thenBy { event -> if (replaceDescription) event.location else event.description })
|
||||
|
||||
var prevCode = ""
|
||||
var prevMonthLabel = ""
|
||||
val now = getNowSeconds()
|
||||
val today = Formatter.getDayTitle(context, Formatter.getDayCodeFromTS(now))
|
||||
|
||||
sorted.forEach {
|
||||
val code = Formatter.getDayCodeFromTS(it.startTS)
|
||||
sorted.forEach { event ->
|
||||
val code = Formatter.getDayCodeFromTS(event.startTS)
|
||||
val monthLabel = Formatter.getLongMonthYear(context, code)
|
||||
if (monthLabel != prevMonthLabel) {
|
||||
val listSectionMonth = ListSectionMonth(monthLabel)
|
||||
|
@ -222,24 +222,24 @@ class EventListWidgetAdapter(val context: Context, val intent: Intent) : RemoteV
|
|||
if (code != prevCode) {
|
||||
val day = Formatter.getDateDayTitle(code)
|
||||
val isToday = day == today
|
||||
val listSection = ListSectionDay(day, code, isToday, !isToday && it.startTS < now)
|
||||
val listSection = ListSectionDay(day, code, isToday, !isToday && event.startTS < now)
|
||||
listItems.add(listSection)
|
||||
prevCode = code
|
||||
}
|
||||
|
||||
val listEvent = ListEvent(
|
||||
it.id!!,
|
||||
it.startTS,
|
||||
it.endTS,
|
||||
it.title,
|
||||
it.description,
|
||||
it.getIsAllDay(),
|
||||
it.color,
|
||||
it.location,
|
||||
it.isPastEvent,
|
||||
it.repeatInterval > 0,
|
||||
it.isTask(),
|
||||
it.isTaskCompleted()
|
||||
event.id!!,
|
||||
event.startTS,
|
||||
event.endTS,
|
||||
event.title,
|
||||
event.description,
|
||||
event.getIsAllDay(),
|
||||
event.color,
|
||||
event.location,
|
||||
event.isPastEvent,
|
||||
event.repeatInterval > 0,
|
||||
event.isTask(),
|
||||
event.isTaskCompleted()
|
||||
)
|
||||
listItems.add(listEvent)
|
||||
}
|
||||
|
|
|
@ -13,14 +13,16 @@ import com.simplemobiletools.calendar.pro.helpers.Converters
|
|||
import com.simplemobiletools.calendar.pro.helpers.REGULAR_EVENT_TYPE_ID
|
||||
import com.simplemobiletools.calendar.pro.interfaces.EventTypesDao
|
||||
import com.simplemobiletools.calendar.pro.interfaces.EventsDao
|
||||
import com.simplemobiletools.calendar.pro.interfaces.TasksDao
|
||||
import com.simplemobiletools.calendar.pro.interfaces.WidgetsDao
|
||||
import com.simplemobiletools.calendar.pro.models.Event
|
||||
import com.simplemobiletools.calendar.pro.models.EventType
|
||||
import com.simplemobiletools.calendar.pro.models.Task
|
||||
import com.simplemobiletools.calendar.pro.models.Widget
|
||||
import com.simplemobiletools.commons.extensions.getProperPrimaryColor
|
||||
import java.util.concurrent.Executors
|
||||
|
||||
@Database(entities = [Event::class, EventType::class, Widget::class], version = 6)
|
||||
@Database(entities = [Event::class, EventType::class, Widget::class, Task::class], version = 7)
|
||||
@TypeConverters(Converters::class)
|
||||
abstract class EventsDatabase : RoomDatabase() {
|
||||
|
||||
|
@ -30,6 +32,8 @@ abstract class EventsDatabase : RoomDatabase() {
|
|||
|
||||
abstract fun WidgetsDao(): WidgetsDao
|
||||
|
||||
abstract fun TasksDao(): TasksDao
|
||||
|
||||
companion object {
|
||||
private var db: EventsDatabase? = null
|
||||
|
||||
|
@ -49,6 +53,7 @@ abstract class EventsDatabase : RoomDatabase() {
|
|||
.addMigrations(MIGRATION_3_4)
|
||||
.addMigrations(MIGRATION_4_5)
|
||||
.addMigrations(MIGRATION_5_6)
|
||||
.addMigrations(MIGRATION_6_7)
|
||||
.build()
|
||||
db!!.openHelper.setWriteAheadLoggingEnabled(true)
|
||||
}
|
||||
|
@ -113,5 +118,14 @@ abstract class EventsDatabase : RoomDatabase() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val MIGRATION_6_7 = object : Migration(6, 7) {
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
database.apply {
|
||||
execSQL("CREATE TABLE IF NOT EXISTS `tasks` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `task_id` INTEGER NOT NULL, `start_ts` INTEGER NOT NULL, `flags` INTEGER NOT NULL)")
|
||||
execSQL("CREATE UNIQUE INDEX IF NOT EXISTS `index_tasks_id_task_id` ON `tasks` (`id`, `task_id`)")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,13 @@ import com.simplemobiletools.commons.extensions.beVisibleIf
|
|||
import com.simplemobiletools.commons.extensions.setupDialogStuff
|
||||
import kotlinx.android.synthetic.main.dialog_delete_event.view.*
|
||||
|
||||
class DeleteEventDialog(val activity: Activity, eventIds: List<Long>, hasRepeatableEvent: Boolean, val callback: (deleteRule: Int) -> Unit) {
|
||||
class DeleteEventDialog(
|
||||
val activity: Activity,
|
||||
eventIds: List<Long>,
|
||||
hasRepeatableEvent: Boolean,
|
||||
isTask: Boolean = false,
|
||||
val callback: (deleteRule: Int) -> Unit
|
||||
) {
|
||||
val dialog: AlertDialog?
|
||||
|
||||
init {
|
||||
|
@ -23,16 +29,22 @@ class DeleteEventDialog(val activity: Activity, eventIds: List<Long>, hasRepeata
|
|||
}
|
||||
|
||||
if (eventIds.size > 1) {
|
||||
delete_event_repeat_description.text = resources.getString(R.string.selection_contains_repetition)
|
||||
delete_event_repeat_description.setText(R.string.selection_contains_repetition)
|
||||
}
|
||||
|
||||
if (isTask) {
|
||||
delete_event_repeat_description.setText(R.string.task_is_repeatable)
|
||||
} else {
|
||||
delete_event_repeat_description.setText(R.string.event_is_repeatable)
|
||||
}
|
||||
}
|
||||
|
||||
dialog = AlertDialog.Builder(activity)
|
||||
.setPositiveButton(R.string.yes) { dialog, which -> dialogConfirmed(view as ViewGroup) }
|
||||
.setNegativeButton(R.string.no, null)
|
||||
.create().apply {
|
||||
activity.setupDialogStuff(view, this)
|
||||
}
|
||||
.setPositiveButton(R.string.yes) { dialog, which -> dialogConfirmed(view as ViewGroup) }
|
||||
.setNegativeButton(R.string.no, null)
|
||||
.create().apply {
|
||||
activity.setupDialogStuff(view, this)
|
||||
}
|
||||
}
|
||||
|
||||
private fun dialogConfirmed(view: ViewGroup) {
|
||||
|
|
|
@ -8,22 +8,28 @@ import com.simplemobiletools.commons.extensions.hideKeyboard
|
|||
import com.simplemobiletools.commons.extensions.setupDialogStuff
|
||||
import kotlinx.android.synthetic.main.dialog_edit_repeating_event.view.*
|
||||
|
||||
class EditRepeatingEventDialog(val activity: SimpleActivity, val callback: (allOccurrences: Int) -> Unit) {
|
||||
class EditRepeatingEventDialog(val activity: SimpleActivity, val isTask: Boolean = false, val callback: (allOccurrences: Int) -> Unit) {
|
||||
var dialog: AlertDialog
|
||||
|
||||
init {
|
||||
val view = (activity.layoutInflater.inflate(R.layout.dialog_edit_repeating_event, null) as ViewGroup).apply {
|
||||
edit_repeating_event_one_only.setOnClickListener { sendResult(0) }
|
||||
edit_repeating_event_this_and_future_occurences.setOnClickListener { sendResult(1)}
|
||||
edit_repeating_event_this_and_future_occurences.setOnClickListener { sendResult(1) }
|
||||
edit_repeating_event_all_occurrences.setOnClickListener { sendResult(2) }
|
||||
|
||||
if (isTask) {
|
||||
edit_repeating_event_title.setText(R.string.task_is_repeatable)
|
||||
} else {
|
||||
edit_repeating_event_title.setText(R.string.event_is_repeatable)
|
||||
}
|
||||
}
|
||||
|
||||
dialog = AlertDialog.Builder(activity)
|
||||
.create().apply {
|
||||
activity.setupDialogStuff(view, this) {
|
||||
hideKeyboard()
|
||||
}
|
||||
.create().apply {
|
||||
activity.setupDialogStuff(view, this) {
|
||||
hideKeyboard()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun sendResult(allOccurrences: Int) {
|
||||
|
|
|
@ -33,6 +33,7 @@ import com.simplemobiletools.calendar.pro.helpers.*
|
|||
import com.simplemobiletools.calendar.pro.helpers.Formatter
|
||||
import com.simplemobiletools.calendar.pro.interfaces.EventTypesDao
|
||||
import com.simplemobiletools.calendar.pro.interfaces.EventsDao
|
||||
import com.simplemobiletools.calendar.pro.interfaces.TasksDao
|
||||
import com.simplemobiletools.calendar.pro.interfaces.WidgetsDao
|
||||
import com.simplemobiletools.calendar.pro.models.*
|
||||
import com.simplemobiletools.calendar.pro.receivers.CalDAVSyncReceiver
|
||||
|
@ -51,6 +52,7 @@ val Context.config: Config get() = Config.newInstance(applicationContext)
|
|||
val Context.eventsDB: EventsDao get() = EventsDatabase.getInstance(applicationContext).EventsDao()
|
||||
val Context.eventTypesDB: EventTypesDao get() = EventsDatabase.getInstance(applicationContext).EventTypesDao()
|
||||
val Context.widgetsDB: WidgetsDao get() = EventsDatabase.getInstance(applicationContext).WidgetsDao()
|
||||
val Context.completedTasksDB: TasksDao get() = EventsDatabase.getInstance(applicationContext).TasksDao()
|
||||
val Context.eventsHelper: EventsHelper get() = EventsHelper(this)
|
||||
val Context.calDAVHelper: CalDAVHelper get() = CalDAVHelper(this)
|
||||
|
||||
|
@ -237,6 +239,7 @@ fun Context.notifyEvent(originalEvent: Event) {
|
|||
val descriptionOrLocation = if (config.replaceDescription) event.location else event.description
|
||||
val content = "$displayedStartDate $timeRange $descriptionOrLocation".trim()
|
||||
ensureBackgroundThread {
|
||||
if (event.isTask()) eventsHelper.updateIsTaskCompleted(event)
|
||||
val notification = getNotification(pendingIntent, event, content)
|
||||
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||
try {
|
||||
|
@ -634,6 +637,7 @@ fun Context.editEvent(event: ListEvent) {
|
|||
Intent(this, getActivityToOpen(event.isTask)).apply {
|
||||
putExtra(EVENT_ID, event.id)
|
||||
putExtra(EVENT_OCCURRENCE_TS, event.startTS)
|
||||
putExtra(IS_TASK_COMPLETED, event.isTaskCompleted)
|
||||
startActivity(this)
|
||||
}
|
||||
}
|
||||
|
@ -653,3 +657,23 @@ fun Context.getDatesWeekDateTime(date: DateTime): String {
|
|||
date.withZone(DateTimeZone.UTC).toString()
|
||||
}
|
||||
}
|
||||
|
||||
fun Context.isTaskCompleted(event: Event): Boolean {
|
||||
if (event.id == null) return false
|
||||
val originalEvent = eventsDB.getTaskWithId(event.id!!)
|
||||
val task = completedTasksDB.getTaskWithIdAndTs(event.id!!, event.startTS)
|
||||
return originalEvent?.isTaskCompleted() == true || task?.isTaskCompleted() == true
|
||||
}
|
||||
|
||||
fun Context.updateTaskCompletion(event: Event, completed: Boolean) {
|
||||
if (completed) {
|
||||
event.flags = event.flags or FLAG_TASK_COMPLETED
|
||||
val task = Task(null, event.id!!, event.startTS, event.flags)
|
||||
completedTasksDB.insertOrUpdate(task)
|
||||
} else {
|
||||
event.flags = event.flags.removeBit(FLAG_TASK_COMPLETED)
|
||||
completedTasksDB.deleteTaskWithIdAndTs(event.id!!, event.startTS)
|
||||
}
|
||||
// mark event as "incomplete" in the main events db
|
||||
eventsDB.updateTaskCompletion(event.id!!, event.flags.removeBit(FLAG_TASK_COMPLETED))
|
||||
}
|
||||
|
|
|
@ -17,13 +17,11 @@ import com.simplemobiletools.calendar.pro.extensions.eventsHelper
|
|||
import com.simplemobiletools.calendar.pro.extensions.getViewBitmap
|
||||
import com.simplemobiletools.calendar.pro.extensions.printBitmap
|
||||
import com.simplemobiletools.calendar.pro.helpers.*
|
||||
import com.simplemobiletools.calendar.pro.helpers.Formatter
|
||||
import com.simplemobiletools.calendar.pro.interfaces.NavigationListener
|
||||
import com.simplemobiletools.calendar.pro.models.Event
|
||||
import com.simplemobiletools.commons.extensions.*
|
||||
import kotlinx.android.synthetic.main.fragment_day.view.*
|
||||
import kotlinx.android.synthetic.main.top_navigation.view.*
|
||||
import java.util.*
|
||||
|
||||
class DayFragment : Fragment() {
|
||||
var mListener: NavigationListener? = null
|
||||
|
@ -129,6 +127,7 @@ class DayFragment : Fragment() {
|
|||
Intent(context, getActivityToOpen(event.isTask())).apply {
|
||||
putExtra(EVENT_ID, event.id)
|
||||
putExtra(EVENT_OCCURRENCE_TS, event.startTS)
|
||||
putExtra(IS_TASK_COMPLETED, event.isTaskCompleted())
|
||||
startActivity(this)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -610,6 +610,7 @@ class WeekFragment : Fragment(), WeeklyCalendar {
|
|||
Intent(context, getActivityToOpen(event.isTask())).apply {
|
||||
putExtra(EVENT_ID, event.id!!)
|
||||
putExtra(EVENT_OCCURRENCE_TS, event.startTS)
|
||||
putExtra(IS_TASK_COMPLETED, event.isTaskCompleted())
|
||||
startActivity(this)
|
||||
}
|
||||
}
|
||||
|
@ -813,6 +814,7 @@ class WeekFragment : Fragment(), WeeklyCalendar {
|
|||
Intent(context, getActivityToOpen(event.isTask())).apply {
|
||||
putExtra(EVENT_ID, event.id)
|
||||
putExtra(EVENT_OCCURRENCE_TS, event.startTS)
|
||||
putExtra(IS_TASK_COMPLETED, event.isTaskCompleted())
|
||||
startActivity(this)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ const val YEAR_LABEL = "year"
|
|||
const val EVENT_ID = "event_id"
|
||||
const val IS_DUPLICATE_INTENT = "is_duplicate_intent"
|
||||
const val EVENT_OCCURRENCE_TS = "event_occurrence_ts"
|
||||
const val IS_TASK_COMPLETED = "is_task_completed"
|
||||
const val NEW_EVENT_START_TS = "new_event_start_ts"
|
||||
const val WEEK_START_TIMESTAMP = "week_start_timestamp"
|
||||
const val NEW_EVENT_SET_HOUR_DURATION = "new_event_set_hour_duration"
|
||||
|
@ -206,6 +207,8 @@ const val EVENT = "EVENT"
|
|||
const val TASK = "TASK"
|
||||
const val START_TS = "START_TS"
|
||||
const val END_TS = "END_TS"
|
||||
const val ORIGINAL_START_TS = "ORIGINAL_START_TS"
|
||||
const val ORIGINAL_END_TS = "ORIGINAL_END_TS"
|
||||
const val REMINDER_1_MINUTES = "REMINDER_1_MINUTES"
|
||||
const val REMINDER_2_MINUTES = "REMINDER_2_MINUTES"
|
||||
const val REMINDER_3_MINUTES = "REMINDER_3_MINUTES"
|
||||
|
@ -219,6 +222,7 @@ const val ATTENDEES = "ATTENDEES"
|
|||
const val AVAILABILITY = "AVAILABILITY"
|
||||
const val EVENT_TYPE_ID = "EVENT_TYPE_ID"
|
||||
const val EVENT_CALENDAR_ID = "EVENT_CALENDAR_ID"
|
||||
const val IS_NEW_EVENT = "IS_NEW_EVENT"
|
||||
|
||||
// actions
|
||||
const val ACTION_MARK_COMPLETED = "ACTION_MARK_COMPLETED"
|
||||
|
|
|
@ -252,7 +252,7 @@ class EventsHelper(val context: Context) {
|
|||
|
||||
fun addEventRepetitionException(parentEventId: Long, occurrenceTS: Long, addToCalDAV: Boolean) {
|
||||
ensureBackgroundThread {
|
||||
val parentEvent = eventsDB.getEventWithId(parentEventId) ?: return@ensureBackgroundThread
|
||||
val parentEvent = eventsDB.getEventOrTaskWithId(parentEventId) ?: return@ensureBackgroundThread
|
||||
var repetitionExceptions = parentEvent.repetitionExceptions
|
||||
repetitionExceptions.add(Formatter.getDayCodeFromTS(occurrenceTS))
|
||||
repetitionExceptions = repetitionExceptions.distinct().toMutableList() as ArrayList<String>
|
||||
|
@ -285,7 +285,6 @@ class EventsHelper(val context: Context) {
|
|||
} else {
|
||||
try {
|
||||
val typesList = context.config.getDisplayEventTypessAsList()
|
||||
events.addAll(eventsDB.getTasksFromTo(fromTS, toTS, typesList))
|
||||
|
||||
events.addAll(eventsDB.getOneTimeEventsFromToWithTypes(toTS, fromTS, typesList).toMutableList() as ArrayList<Event>)
|
||||
} catch (e: Exception) {
|
||||
|
@ -317,6 +316,7 @@ class EventsHelper(val context: Context) {
|
|||
}
|
||||
|
||||
events.forEach {
|
||||
if (it.isTask()) updateIsTaskCompleted(it)
|
||||
it.updateIsPastEvent()
|
||||
val originalEvent = eventsDB.getEventWithId(it.id!!)
|
||||
if (originalEvent != null &&
|
||||
|
@ -364,13 +364,13 @@ class EventsHelper(val context: Context) {
|
|||
if (displayEventTypes.isEmpty()) {
|
||||
return ArrayList()
|
||||
} else {
|
||||
eventsDB.getRepeatableEventsFromToWithTypes(toTS, context.config.getDisplayEventTypessAsList()).toMutableList() as ArrayList<Event>
|
||||
eventsDB.getRepeatableEventsOrTasksWithTypes(toTS, context.config.getDisplayEventTypessAsList()).toMutableList() as ArrayList<Event>
|
||||
}
|
||||
} else {
|
||||
if (eventId == -1L) {
|
||||
eventsDB.getRepeatableEventsFromToWithTypes(toTS).toMutableList() as ArrayList<Event>
|
||||
eventsDB.getRepeatableEventsOrTasksWithTypes(toTS).toMutableList() as ArrayList<Event>
|
||||
} else {
|
||||
eventsDB.getRepeatableEventFromToWithId(eventId, toTS).toMutableList() as ArrayList<Event>
|
||||
eventsDB.getRepeatableEventsOrTasksWithId(eventId, toTS).toMutableList() as ArrayList<Event>
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -482,10 +482,18 @@ class EventsHelper(val context: Context) {
|
|||
return events
|
||||
}
|
||||
|
||||
fun updateIsTaskCompleted(event: Event) {
|
||||
val task = context.completedTasksDB.getTaskWithIdAndTs(event.id!!, startTs = event.startTS)
|
||||
event.flags = task?.flags ?: event.flags
|
||||
}
|
||||
|
||||
fun getRunningEventsOrTasks(): List<Event> {
|
||||
val ts = getNowSeconds()
|
||||
val events = eventsDB.getOneTimeEventsOrTasksFromTo(ts, ts).toMutableList() as ArrayList<Event>
|
||||
events.addAll(getRepeatableEventsFor(ts, ts))
|
||||
events.forEach {
|
||||
if (it.isTask()) updateIsTaskCompleted(it)
|
||||
}
|
||||
return events
|
||||
}
|
||||
|
||||
|
|
|
@ -42,14 +42,14 @@ interface EventsDao {
|
|||
@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<Long>): List<Event>
|
||||
|
||||
@Query("SELECT * FROM events WHERE start_ts <= :toTS AND repeat_interval != 0 AND type = $TYPE_EVENT")
|
||||
fun getRepeatableEventsFromToWithTypes(toTS: Long): List<Event>
|
||||
@Query("SELECT * FROM events WHERE start_ts <= :toTS AND repeat_interval != 0 AND (type = $TYPE_EVENT OR type = $TYPE_TASK)")
|
||||
fun getRepeatableEventsOrTasksWithTypes(toTS: Long): List<Event>
|
||||
|
||||
@Query("SELECT * FROM events WHERE id = :id AND start_ts <= :toTS AND repeat_interval != 0 AND type = $TYPE_EVENT")
|
||||
fun getRepeatableEventFromToWithId(id: Long, toTS: Long): List<Event>
|
||||
@Query("SELECT * FROM events WHERE id = :id AND start_ts <= :toTS AND repeat_interval != 0 AND (type = $TYPE_EVENT OR type = $TYPE_TASK)")
|
||||
fun getRepeatableEventsOrTasksWithId(id: Long, toTS: Long): List<Event>
|
||||
|
||||
@Query("SELECT * FROM events WHERE start_ts <= :toTS AND start_ts != 0 AND repeat_interval != 0 AND event_type IN (:eventTypeIds) AND type = $TYPE_EVENT")
|
||||
fun getRepeatableEventsFromToWithTypes(toTS: Long, eventTypeIds: List<Long>): List<Event>
|
||||
@Query("SELECT * FROM events WHERE start_ts <= :toTS AND start_ts != 0 AND repeat_interval != 0 AND event_type IN (:eventTypeIds) AND (type = $TYPE_EVENT OR type = $TYPE_TASK)")
|
||||
fun getRepeatableEventsOrTasksWithTypes(toTS: Long, eventTypeIds: List<Long>): List<Event>
|
||||
|
||||
@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<Long>): List<Event>
|
||||
|
@ -106,12 +106,13 @@ interface EventsDao {
|
|||
@Query("UPDATE events SET import_id = :importId, source = :source WHERE id = :id AND type = $TYPE_EVENT")
|
||||
fun updateEventImportIdAndSource(importId: String, source: String, id: Long)
|
||||
|
||||
@Query("UPDATE events SET repeat_limit = :repeatLimit WHERE id = :id AND type = $TYPE_EVENT")
|
||||
@Query("UPDATE events SET repeat_limit = :repeatLimit WHERE id = :id AND (type = $TYPE_EVENT OR type = $TYPE_TASK)")
|
||||
fun updateEventRepetitionLimit(repeatLimit: Long, id: Long)
|
||||
|
||||
@Query("UPDATE events SET repetition_exceptions = :repetitionExceptions WHERE id = :id AND type = $TYPE_EVENT")
|
||||
@Query("UPDATE events SET repetition_exceptions = :repetitionExceptions WHERE id = :id AND (type = $TYPE_EVENT OR type = $TYPE_TASK)")
|
||||
fun updateEventRepetitionExceptions(repetitionExceptions: String, id: Long)
|
||||
|
||||
@Deprecated("Use Context.updateTaskCompletion() instead unless you know what you are doing.")
|
||||
@Query("UPDATE events SET flags = :newFlags WHERE id = :id")
|
||||
fun updateTaskCompletion(id: Long, newFlags: Int)
|
||||
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
package com.simplemobiletools.calendar.pro.interfaces
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import com.simplemobiletools.calendar.pro.models.Task
|
||||
|
||||
@Dao
|
||||
interface TasksDao {
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
fun insertOrUpdate(task: Task): Long
|
||||
|
||||
@Query("SELECT * FROM tasks WHERE task_id = :id AND start_ts = :startTs")
|
||||
fun getTaskWithIdAndTs(id: Long, startTs: Long): Task?
|
||||
|
||||
@Query("DELETE FROM tasks WHERE task_id = :id AND start_ts = :startTs")
|
||||
fun deleteTaskWithIdAndTs(id: Long, startTs: Long)
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package com.simplemobiletools.calendar.pro.models
|
||||
|
||||
import androidx.room.ColumnInfo
|
||||
import androidx.room.Entity
|
||||
import androidx.room.Index
|
||||
import androidx.room.PrimaryKey
|
||||
import com.simplemobiletools.calendar.pro.helpers.FLAG_TASK_COMPLETED
|
||||
|
||||
@Entity(tableName = "tasks", indices = [(Index(value = ["id", "task_id"], unique = true))])
|
||||
data class Task(
|
||||
@PrimaryKey(autoGenerate = true) var id: Long?,
|
||||
@ColumnInfo(name = "task_id") var task_id: Long,
|
||||
@ColumnInfo(name = "start_ts") var startTS: Long = 0L,
|
||||
@ColumnInfo(name = "flags") var flags: Int = 0,
|
||||
) {
|
||||
fun isTaskCompleted() = flags and FLAG_TASK_COMPLETED != 0
|
||||
}
|
|
@ -5,9 +5,9 @@ import android.content.Intent
|
|||
import com.simplemobiletools.calendar.pro.extensions.cancelNotification
|
||||
import com.simplemobiletools.calendar.pro.extensions.cancelPendingIntent
|
||||
import com.simplemobiletools.calendar.pro.extensions.eventsDB
|
||||
import com.simplemobiletools.calendar.pro.extensions.updateTaskCompletion
|
||||
import com.simplemobiletools.calendar.pro.helpers.ACTION_MARK_COMPLETED
|
||||
import com.simplemobiletools.calendar.pro.helpers.EVENT_ID
|
||||
import com.simplemobiletools.calendar.pro.helpers.FLAG_TASK_COMPLETED
|
||||
|
||||
class MarkCompletedService : IntentService("MarkCompleted") {
|
||||
|
||||
|
@ -17,8 +17,7 @@ class MarkCompletedService : IntentService("MarkCompleted") {
|
|||
val taskId = intent.getLongExtra(EVENT_ID, 0L)
|
||||
val task = eventsDB.getTaskWithId(taskId)
|
||||
if (task != null) {
|
||||
task.flags = task.flags or FLAG_TASK_COMPLETED
|
||||
eventsDB.updateTaskCompletion(task.id!!, task.flags)
|
||||
updateTaskCompletion(task, true)
|
||||
cancelPendingIntent(task.id!!)
|
||||
cancelNotification(task.id!!)
|
||||
}
|
||||
|
|
|
@ -114,7 +114,7 @@
|
|||
tools:text="00:00" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/event_date_time_divider"
|
||||
android:id="@+id/task_date_time_divider"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1px"
|
||||
android:layout_below="@+id/task_date"
|
||||
|
@ -124,23 +124,23 @@
|
|||
android:importantForAccessibility="no" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/event_reminder_image"
|
||||
android:id="@+id/task_reminder_image"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_below="@+id/event_date_time_divider"
|
||||
android:layout_alignTop="@+id/event_reminder_1"
|
||||
android:layout_alignBottom="@+id/event_reminder_1"
|
||||
android:layout_below="@+id/task_date_time_divider"
|
||||
android:layout_alignTop="@+id/task_reminder_1"
|
||||
android:layout_alignBottom="@+id/task_reminder_1"
|
||||
android:layout_marginStart="@dimen/normal_margin"
|
||||
android:padding="@dimen/medium_margin"
|
||||
android:src="@drawable/ic_bell_vector" />
|
||||
|
||||
<com.simplemobiletools.commons.views.MyTextView
|
||||
android:id="@+id/event_reminder_1"
|
||||
android:id="@+id/task_reminder_1"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/event_date_time_divider"
|
||||
android:layout_below="@+id/task_date_time_divider"
|
||||
android:layout_marginStart="@dimen/small_margin"
|
||||
android:layout_toEndOf="@+id/event_reminder_image"
|
||||
android:layout_toEndOf="@+id/task_reminder_image"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:ellipsize="end"
|
||||
android:lines="1"
|
||||
|
@ -152,11 +152,11 @@
|
|||
tools:text="@string/add_another_reminder" />
|
||||
|
||||
<com.simplemobiletools.commons.views.MyTextView
|
||||
android:id="@+id/event_reminder_2"
|
||||
android:id="@+id/task_reminder_2"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/event_reminder_1"
|
||||
android:layout_alignStart="@+id/event_reminder_1"
|
||||
android:layout_below="@+id/task_reminder_1"
|
||||
android:layout_alignStart="@+id/task_reminder_1"
|
||||
android:alpha="0.4"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:ellipsize="end"
|
||||
|
@ -171,11 +171,11 @@
|
|||
tools:text="@string/add_another_reminder" />
|
||||
|
||||
<com.simplemobiletools.commons.views.MyTextView
|
||||
android:id="@+id/event_reminder_3"
|
||||
android:id="@+id/task_reminder_3"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/event_reminder_2"
|
||||
android:layout_alignStart="@+id/event_reminder_1"
|
||||
android:layout_below="@+id/task_reminder_2"
|
||||
android:layout_alignStart="@+id/task_reminder_1"
|
||||
android:alpha="0.4"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:ellipsize="end"
|
||||
|
@ -190,49 +190,146 @@
|
|||
tools:text="@string/add_another_reminder" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/event_caldav_calendar_divider"
|
||||
android:id="@+id/task_caldav_calendar_divider"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1px"
|
||||
android:layout_below="@+id/event_reminder_3"
|
||||
android:layout_below="@+id/task_reminder_3"
|
||||
android:layout_marginTop="@dimen/medium_margin"
|
||||
android:layout_marginBottom="@dimen/medium_margin"
|
||||
android:background="@color/divider_grey"
|
||||
android:importantForAccessibility="no" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/event_type_image"
|
||||
android:id="@+id/task_repetition_image"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_below="@+id/event_caldav_calendar_divider"
|
||||
android:layout_alignTop="@+id/event_type_holder"
|
||||
android:layout_alignBottom="@+id/event_type_holder"
|
||||
android:layout_below="@+id/task_caldav_calendar_divider"
|
||||
android:layout_alignTop="@+id/task_repetition"
|
||||
android:layout_alignBottom="@+id/task_repetition"
|
||||
android:layout_marginStart="@dimen/normal_margin"
|
||||
android:padding="@dimen/medium_margin"
|
||||
android:src="@drawable/ic_repeat_vector" />
|
||||
|
||||
<com.simplemobiletools.commons.views.MyTextView
|
||||
android:id="@+id/task_repetition"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/task_caldav_calendar_divider"
|
||||
android:layout_marginStart="@dimen/small_margin"
|
||||
android:layout_toEndOf="@+id/task_repetition_image"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:paddingTop="@dimen/normal_margin"
|
||||
android:paddingEnd="@dimen/activity_margin"
|
||||
android:paddingBottom="@dimen/normal_margin"
|
||||
android:textSize="@dimen/day_text_size"
|
||||
tools:text="@string/no_repetition" />
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/task_repetition_rule_holder"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/task_repetition"
|
||||
android:layout_alignStart="@+id/task_repetition"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:visibility="gone">
|
||||
|
||||
<com.simplemobiletools.commons.views.MyTextView
|
||||
android:id="@+id/task_repetition_rule_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:clickable="false"
|
||||
android:paddingTop="@dimen/activity_margin"
|
||||
android:paddingBottom="@dimen/activity_margin"
|
||||
android:text="@string/repeat_on"
|
||||
android:textSize="@dimen/day_text_size" />
|
||||
|
||||
<com.simplemobiletools.commons.views.MyTextView
|
||||
android:id="@+id/task_repetition_rule"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_toEndOf="@+id/task_repetition_rule_label"
|
||||
android:clickable="false"
|
||||
android:gravity="end"
|
||||
android:padding="@dimen/activity_margin"
|
||||
android:text="@string/every_day"
|
||||
android:textSize="@dimen/day_text_size" />
|
||||
</RelativeLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/task_repetition_limit_holder"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/task_repetition_rule_holder"
|
||||
android:layout_alignStart="@+id/task_repetition"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:visibility="gone">
|
||||
|
||||
<com.simplemobiletools.commons.views.MyTextView
|
||||
android:id="@+id/task_repetition_limit_label"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_toStartOf="@+id/task_repetition_limit"
|
||||
android:clickable="false"
|
||||
android:paddingTop="@dimen/activity_margin"
|
||||
android:paddingBottom="@dimen/activity_margin"
|
||||
android:text="@string/repeat_till"
|
||||
android:textSize="@dimen/day_text_size" />
|
||||
|
||||
<com.simplemobiletools.commons.views.MyTextView
|
||||
android:id="@+id/task_repetition_limit"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:clickable="false"
|
||||
android:padding="@dimen/activity_margin"
|
||||
android:text="@string/forever"
|
||||
android:textSize="@dimen/day_text_size" />
|
||||
</RelativeLayout>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/task_repetition_divider"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1px"
|
||||
android:layout_below="@+id/task_repetition_limit_holder"
|
||||
android:layout_marginTop="@dimen/medium_margin"
|
||||
android:background="@color/divider_grey"
|
||||
android:importantForAccessibility="no" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/task_type_image"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_below="@+id/task_repetition_divider"
|
||||
android:layout_alignTop="@+id/task_type_holder"
|
||||
android:layout_alignBottom="@+id/task_type_holder"
|
||||
android:layout_marginStart="@dimen/normal_margin"
|
||||
android:padding="@dimen/medium_margin"
|
||||
android:src="@drawable/ic_color_vector" />
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/event_type_holder"
|
||||
android:id="@+id/task_type_holder"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/event_caldav_calendar_divider"
|
||||
android:layout_below="@+id/task_repetition_divider"
|
||||
android:layout_marginTop="@dimen/medium_margin"
|
||||
android:layout_marginBottom="@dimen/medium_margin"
|
||||
android:layout_toEndOf="@+id/event_type_image"
|
||||
android:layout_toEndOf="@+id/task_type_image"
|
||||
android:background="?attr/selectableItemBackground">
|
||||
|
||||
<com.simplemobiletools.commons.views.MyTextView
|
||||
android:id="@+id/event_type"
|
||||
android:id="@+id/task_type"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/small_margin"
|
||||
android:layout_marginEnd="@dimen/medium_margin"
|
||||
android:layout_toStartOf="@+id/event_type_color"
|
||||
android:layout_toStartOf="@+id/task_type_color"
|
||||
android:paddingTop="@dimen/normal_margin"
|
||||
android:paddingBottom="@dimen/normal_margin"
|
||||
android:textSize="@dimen/day_text_size" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/event_type_color"
|
||||
android:id="@+id/task_type_color"
|
||||
android:layout_width="@dimen/color_sample_size"
|
||||
android:layout_height="@dimen/color_sample_size"
|
||||
android:layout_alignParentEnd="true"
|
||||
|
@ -243,10 +340,10 @@
|
|||
</RelativeLayout>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/event_type_divider"
|
||||
android:id="@+id/task_type_divider"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1px"
|
||||
android:layout_below="@+id/event_type_holder"
|
||||
android:layout_below="@+id/task_type_holder"
|
||||
android:background="@color/divider_grey"
|
||||
android:importantForAccessibility="no" />
|
||||
|
||||
|
@ -255,7 +352,7 @@
|
|||
style="@style/ColoredButtonStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/event_type_divider"
|
||||
android:layout_below="@+id/task_type_divider"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_marginTop="@dimen/activity_margin"
|
||||
android:text="@string/mark_completed"
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
<string name="repeat_till">تكرار حتى</string>
|
||||
<string name="forever">للأبد</string>
|
||||
<string name="event_is_repeatable">الحدث متكرر</string>
|
||||
<string name="task_is_repeatable">The task is repeatable</string>
|
||||
<string name="selection_contains_repetition">الإختيار يحتوى على احداث مكررة</string>
|
||||
<string name="delete_one_only">حذف النسخ المحددة فقط</string>
|
||||
<string name="delete_future_occurrences">حذف هذه النسخة وكل النسخ المستقبلية</string>
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
<string name="repeat_till">Bu vaxta qədər təkrarla</string>
|
||||
<string name="forever">Sonsuz</string>
|
||||
<string name="event_is_repeatable">Bu hadisə təkrarlanabilər</string>
|
||||
<string name="task_is_repeatable">The task is repeatable</string>
|
||||
<string name="selection_contains_repetition">Seçim təkrarlanan hadisələr ehtiva edir</string>
|
||||
<string name="delete_one_only">Yalnız seçilmiş hadisəni sil</string>
|
||||
<string name="delete_future_occurrences">Bunu və bütün gələcək hadisələri sil</string>
|
||||
|
@ -279,4 +280,4 @@
|
|||
Haven't found some strings? There's more at
|
||||
https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res
|
||||
-->
|
||||
</resources>
|
||||
</resources>
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
<string name="repeat_till">Repeat till</string>
|
||||
<string name="forever">Forever</string>
|
||||
<string name="event_is_repeatable">The event is repeatable</string>
|
||||
<string name="task_is_repeatable">The task is repeatable</string>
|
||||
<string name="selection_contains_repetition">The selection contains repeating events</string>
|
||||
<string name="delete_one_only">Delete the selected occurrence only</string>
|
||||
<string name="delete_future_occurrences">Delete this and all future occurrences</string>
|
||||
|
@ -285,4 +286,4 @@
|
|||
Haven't found some strings? There's more at
|
||||
https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res
|
||||
-->
|
||||
</resources>
|
||||
</resources>
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
<string name="repeat_till">Повтаряй до</string>
|
||||
<string name="forever">Завинаги</string>
|
||||
<string name="event_is_repeatable">Събитието се повтаря</string>
|
||||
<string name="task_is_repeatable">The task is repeatable</string>
|
||||
<string name="selection_contains_repetition">Изборът съдържа само повтарящи се събития</string>
|
||||
<string name="delete_one_only">Изтрийте само избраното събитие</string>
|
||||
<string name="delete_future_occurrences">Изтрийте това събитие и всички бъдещи събития</string>
|
||||
|
@ -279,4 +280,4 @@
|
|||
Haven't found some strings? There's more at
|
||||
https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res
|
||||
-->
|
||||
</resources>
|
||||
</resources>
|
||||
|
|
|
@ -58,6 +58,7 @@
|
|||
<string name="repeat_till">পুনরাবৃত্তি ততক্ষণ পর্যন্ত</string>
|
||||
<string name="forever">চিরতরে</string>
|
||||
<string name="event_is_repeatable">ঘটনাটি পুনরাবৃত্তিযোগ্য</string>
|
||||
<string name="task_is_repeatable">The task is repeatable</string>
|
||||
<string name="selection_contains_repetition">সিলেকশনটিতে পুনরাবৃত্তি ইভেন্টগুলি রয়েছে</string>
|
||||
<string name="delete_one_only">কেবলমাত্র সিলেক্টেড ঘটনা মুছুন</string>
|
||||
<string name="delete_future_occurrences">এটি এবং ভবিষ্যতের সমস্ত ঘটনা মুছুন</string>
|
||||
|
@ -278,4 +279,4 @@
|
|||
Haven't found some strings? There's more at
|
||||
https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res
|
||||
-->
|
||||
</resources>
|
||||
</resources>
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
<string name="repeat_till">addegouezhout betek</string>
|
||||
<string name="forever">Da viken</string>
|
||||
<string name="event_is_repeatable">An darvoud a c\'hall addegouezhout</string>
|
||||
<string name="task_is_repeatable">The task is repeatable</string>
|
||||
<string name="selection_contains_repetition">Darvoudoù a c\'hall addegouezhout a zo en diuzad</string>
|
||||
<string name="delete_one_only">Dilemel an degouezh bremanel nemetken</string>
|
||||
<string name="delete_future_occurrences">Delete this and all future occurrences</string>
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
<string name="repeat_till">Repeteix fins</string>
|
||||
<string name="forever">Per sempre</string>
|
||||
<string name="event_is_repeatable">L\'esdeveniment és repetible</string>
|
||||
<string name="task_is_repeatable">The task is repeatable</string>
|
||||
<string name="selection_contains_repetition">La selecció conté esdeveniments que es repeteixen</string>
|
||||
<string name="delete_one_only">Suprimeix només l\'ocurrència seleccionada</string>
|
||||
<string name="delete_future_occurrences">Suprimeix aquesta i totes les ocurrències futures</string>
|
||||
|
@ -279,4 +280,4 @@
|
|||
Haven't found some strings? There's more at
|
||||
https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res
|
||||
-->
|
||||
</resources>
|
||||
</resources>
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
<string name="repeat_till">Opakovat do</string>
|
||||
<string name="forever">Navždy</string>
|
||||
<string name="event_is_repeatable">Událost se opakuje</string>
|
||||
<string name="task_is_repeatable">The task is repeatable</string>
|
||||
<string name="selection_contains_repetition">Výběr zahrnuje opakující se události</string>
|
||||
<string name="delete_one_only">Vymazat pouze vybrané výskyty</string>
|
||||
<string name="delete_future_occurrences">Vymazat tento a jakékoliv budoucí výskyty</string>
|
||||
|
@ -282,4 +283,4 @@
|
|||
Haven't found some strings? There's more at
|
||||
https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res
|
||||
-->
|
||||
</resources>
|
||||
</resources>
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
<string name="repeat_till">Gentag indtil</string>
|
||||
<string name="forever">Ingen slutdato</string>
|
||||
<string name="event_is_repeatable">Begivenheden kan gentages</string>
|
||||
<string name="task_is_repeatable">The task is repeatable</string>
|
||||
<string name="selection_contains_repetition">Valget indeholder gentagne begivenheder</string>
|
||||
<string name="delete_one_only">Slet kun denne forekomst</string>
|
||||
<string name="delete_future_occurrences">Slet denne og alle fremtidige forekomster</string>
|
||||
|
@ -279,4 +280,4 @@
|
|||
Haven't found some strings? There's more at
|
||||
https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res
|
||||
-->
|
||||
</resources>
|
||||
</resources>
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
<string name="repeat_till">Wiederholen bis</string>
|
||||
<string name="forever">unendlich</string>
|
||||
<string name="event_is_repeatable">Termin ist wiederholbar</string>
|
||||
<string name="task_is_repeatable">The task is repeatable</string>
|
||||
<string name="selection_contains_repetition">Die Auswahl enthält wiederkehrende Termine</string>
|
||||
<string name="delete_one_only">Nur die ausgewählte Wiederholung löschen</string>
|
||||
<string name="delete_future_occurrences">Diese und zukünftige Wiederholungen löschen</string>
|
||||
|
@ -279,4 +280,4 @@
|
|||
Haven't found some strings? There's more at
|
||||
https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res
|
||||
-->
|
||||
</resources>
|
||||
</resources>
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
<string name="repeat_till">Επανάληψη μέχρι</string>
|
||||
<string name="forever">Για πάντα</string>
|
||||
<string name="event_is_repeatable">Η εκδήλωση είναι επαναλαμβανόμενη</string>
|
||||
<string name="task_is_repeatable">The task is repeatable</string>
|
||||
<string name="selection_contains_repetition">Η επιλογή περιέχει επαναλαμβανόμενες εκδηλώσεις</string>
|
||||
<string name="delete_one_only">Διαγράψτε μόνο το επιλεγμένο περιστατικό</string>
|
||||
<string name="delete_future_occurrences">Διαγράψτε αυτό και όλα τα μελλοντικά συμβάντα</string>
|
||||
|
@ -279,4 +280,4 @@
|
|||
Haven't found some strings? There's more at
|
||||
https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res
|
||||
-->
|
||||
</resources>
|
||||
</resources>
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
<string name="repeat_till">Ripeti ĝis</string>
|
||||
<string name="forever">Forever</string>
|
||||
<string name="event_is_repeatable">The event is repeatable</string>
|
||||
<string name="task_is_repeatable">The task is repeatable</string>
|
||||
<string name="selection_contains_repetition">The selection contains repeating events</string>
|
||||
<string name="delete_one_only">Delete the selected occurrence only</string>
|
||||
<string name="delete_future_occurrences">Delete this and all future occurrences</string>
|
||||
|
@ -279,4 +280,4 @@
|
|||
Haven't found some strings? There's more at
|
||||
https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res
|
||||
-->
|
||||
</resources>
|
||||
</resources>
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
<string name="repeat_till">Repetir hasta</string>
|
||||
<string name="forever">Siempre</string>
|
||||
<string name="event_is_repeatable">Este evento se repite</string>
|
||||
<string name="task_is_repeatable">The task is repeatable</string>
|
||||
<string name="selection_contains_repetition">La selección contiene repetición de eventos</string>
|
||||
<string name="delete_one_only">Eliminar solo el evento seleccionado</string>
|
||||
<string name="delete_future_occurrences">Eliminar el evento y repeticiones futuras</string>
|
||||
|
@ -279,4 +280,4 @@
|
|||
Haven't found some strings? There's more at
|
||||
https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res
|
||||
-->
|
||||
</resources>
|
||||
</resources>
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
<string name="repeat_till">Korda kuni</string>
|
||||
<string name="forever">Igavesti</string>
|
||||
<string name="event_is_repeatable">Sündmus on korratav</string>
|
||||
<string name="task_is_repeatable">The task is repeatable</string>
|
||||
<string name="selection_contains_repetition">Valik sisaldab korduvaid sündmusi</string>
|
||||
<string name="delete_one_only">Delete the selected occurrence only</string>
|
||||
<string name="delete_future_occurrences">Delete this and all future occurrences</string>
|
||||
|
@ -279,4 +280,4 @@
|
|||
Haven't found some strings? There's more at
|
||||
https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res
|
||||
-->
|
||||
</resources>
|
||||
</resources>
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
<string name="repeat_till">Noiz arte errepikatu</string>
|
||||
<string name="forever">Betiko</string>
|
||||
<string name="event_is_repeatable">Gertaera errepikagarria da</string>
|
||||
<string name="task_is_repeatable">The task is repeatable</string>
|
||||
<string name="selection_contains_repetition">Hautaketak errepikatzen diren gertaerak ditu</string>
|
||||
<string name="delete_one_only">Ezabatu hautatutako gertaera soilik</string>
|
||||
<string name="delete_future_occurrences">Ezabatu gertaera hau eta datozen guztiak</string>
|
||||
|
@ -279,4 +280,4 @@
|
|||
Haven't found some strings? There's more at
|
||||
https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res
|
||||
-->
|
||||
</resources>
|
||||
</resources>
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
<string name="repeat_till">Toista kunnes</string>
|
||||
<string name="forever">Aina</string>
|
||||
<string name="event_is_repeatable">Tapahtuma on toistettavissa</string>
|
||||
<string name="task_is_repeatable">The task is repeatable</string>
|
||||
<string name="selection_contains_repetition">Valinta sisältää toistettavia tapahtumia</string>
|
||||
<string name="delete_one_only">Poista vain valittu esiintymä</string>
|
||||
<string name="delete_future_occurrences">Poista tämä ja seuraavat esiintymät</string>
|
||||
|
@ -279,4 +280,4 @@
|
|||
Haven't found some strings? There's more at
|
||||
https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res
|
||||
-->
|
||||
</resources>
|
||||
</resources>
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
<string name="repeat_till">Répéter jusqu\'à</string>
|
||||
<string name="forever">Éternellement</string>
|
||||
<string name="event_is_repeatable">L\'évènement est périodique</string>
|
||||
<string name="task_is_repeatable">The task is repeatable</string>
|
||||
<string name="selection_contains_repetition">La sélection contient des évènements périodiques</string>
|
||||
<string name="delete_one_only">Supprimer seulement l\'occurrence sélectionnée</string>
|
||||
<string name="delete_future_occurrences">Supprimer cette occurrence et toutes les occurrences futures</string>
|
||||
|
@ -279,4 +280,4 @@
|
|||
Haven't found some strings? There's more at
|
||||
https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res
|
||||
-->
|
||||
</resources>
|
||||
</resources>
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
<string name="repeat_till">Repetir ata</string>
|
||||
<string name="forever">Sempre</string>
|
||||
<string name="event_is_repeatable">O evento é repetible</string>
|
||||
<string name="task_is_repeatable">The task is repeatable</string>
|
||||
<string name="selection_contains_repetition">A selección contén eventos recurrentes</string>
|
||||
<string name="delete_one_only">Eliminar só o evento seleccionado</string>
|
||||
<string name="delete_future_occurrences">Eliminar este e todos os eventos futuros</string>
|
||||
|
@ -279,4 +280,4 @@
|
|||
Haven't found some strings? There's more at
|
||||
https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res
|
||||
-->
|
||||
</resources>
|
||||
</resources>
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
<string name="repeat_till">Repeat till</string>
|
||||
<string name="forever">Forever</string>
|
||||
<string name="event_is_repeatable">The event is repeatable</string>
|
||||
<string name="task_is_repeatable">The task is repeatable</string>
|
||||
<string name="selection_contains_repetition">The selection contains repeating events</string>
|
||||
<string name="delete_one_only">Delete the selected occurrence only</string>
|
||||
<string name="delete_future_occurrences">Delete this and all future occurrences</string>
|
||||
|
@ -279,4 +280,4 @@
|
|||
Haven't found some strings? There's more at
|
||||
https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res
|
||||
-->
|
||||
</resources>
|
||||
</resources>
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
<string name="repeat_till">Ponavljaj do</string>
|
||||
<string name="forever">Zauvijek</string>
|
||||
<string name="event_is_repeatable">Događaj se ponavlja</string>
|
||||
<string name="task_is_repeatable">The task is repeatable</string>
|
||||
<string name="selection_contains_repetition">Odabir sadrži ponavljajuće događaje</string>
|
||||
<string name="delete_one_only">Izbriši samo odabrano ponavljanje</string>
|
||||
<string name="delete_future_occurrences">Izbriši ovo i sva buduća ponavljanja</string>
|
||||
|
@ -282,4 +283,4 @@
|
|||
Haven't found some strings? There's more at
|
||||
https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res
|
||||
-->
|
||||
</resources>
|
||||
</resources>
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
<string name="repeat_till">Ismétlés eddig:</string>
|
||||
<string name="forever">Örökké</string>
|
||||
<string name="event_is_repeatable">Az esemény ismétlődik</string>
|
||||
<string name="task_is_repeatable">The task is repeatable</string>
|
||||
<string name="selection_contains_repetition">A kiválasztás ismétlődő eseményeket tartalmaz</string>
|
||||
<string name="delete_one_only">Csak a kiválasztott előfordulás törlése</string>
|
||||
<string name="delete_future_occurrences">Ez és az összes jövőbeli előfordulás törlése</string>
|
||||
|
@ -279,4 +280,4 @@
|
|||
Haven't found some strings? There's more at
|
||||
https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res
|
||||
-->
|
||||
</resources>
|
||||
</resources>
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
<string name="repeat_till">Ulangi sampai</string>
|
||||
<string name="forever">Selamanya</string>
|
||||
<string name="event_is_repeatable">Acara berulang</string>
|
||||
<string name="task_is_repeatable">The task is repeatable</string>
|
||||
<string name="selection_contains_repetition">Acara yang dipilih berisi acara yang berulang</string>
|
||||
<string name="delete_one_only">Hapus acara ini saja</string>
|
||||
<string name="delete_future_occurrences">Hapus acara ini dan semua perulangannya</string>
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
<string name="repeat_till">Ripeti fino a</string>
|
||||
<string name="forever">Per sempre</string>
|
||||
<string name="event_is_repeatable">L\'evento è ripetibile</string>
|
||||
<string name="task_is_repeatable">The task is repeatable</string>
|
||||
<string name="selection_contains_repetition">La selezione contiene eventi ripetuti</string>
|
||||
<string name="delete_one_only">Elimina solamente l\'occorenza selezionata</string>
|
||||
<string name="delete_future_occurrences">Rimuovi questo e tutte le future occorrenze</string>
|
||||
|
@ -279,4 +280,4 @@
|
|||
Haven't found some strings? There's more at
|
||||
https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res
|
||||
-->
|
||||
</resources>
|
||||
</resources>
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
<string name="repeat_till">חזרה עד</string>
|
||||
<string name="forever">לנצח</string>
|
||||
<string name="event_is_repeatable">האירוע ניתן לחזרה</string>
|
||||
<string name="task_is_repeatable">The task is repeatable</string>
|
||||
<string name="selection_contains_repetition">הבחירה כוללת אירועים חוזרים</string>
|
||||
<string name="delete_one_only">מחיקת אירוע בודד</string>
|
||||
<string name="delete_future_occurrences">מחיקת כל האירועים העתידיים בסדרה</string>
|
||||
|
|
|
@ -60,6 +60,7 @@
|
|||
<string name="repeat_till">Repeat till</string>
|
||||
<string name="forever">Forever</string>
|
||||
<string name="event_is_repeatable">The event is repeatable</string>
|
||||
<string name="task_is_repeatable">The task is repeatable</string>
|
||||
<string name="selection_contains_repetition">The selection contains repeating events</string>
|
||||
<string name="delete_one_only">Delete the selected occurrence only</string>
|
||||
<string name="delete_future_occurrences">Delete this and all future occurrences</string>
|
||||
|
@ -277,4 +278,4 @@
|
|||
Haven't found some strings? There's more at
|
||||
https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res
|
||||
-->
|
||||
</resources>
|
||||
</resources>
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
<string name="repeat_till">까지 반복</string>
|
||||
<string name="forever">영원히</string>
|
||||
<string name="event_is_repeatable">반복 일정입니다</string>
|
||||
<string name="task_is_repeatable">The task is repeatable</string>
|
||||
<string name="selection_contains_repetition">선택한 항목에 반복되는 일정들이 있습니다</string>
|
||||
<string name="delete_one_only">선택한 항목만 삭제</string>
|
||||
<string name="delete_future_occurrences">반복되는 일정까지 삭제</string>
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
<string name="repeat_till">Kartoti iki</string>
|
||||
<string name="forever">Amžinai</string>
|
||||
<string name="event_is_repeatable">Įvykis yra pasikartojantis</string>
|
||||
<string name="task_is_repeatable">The task is repeatable</string>
|
||||
<string name="selection_contains_repetition">Žymėjime yra pasikartojančių įvykių</string>
|
||||
<string name="delete_one_only">Ištrinti tik pasirinktą pasikartojimą</string>
|
||||
<string name="delete_future_occurrences">Ištrinti šį ir visus būsimus pasikartojimus</string>
|
||||
|
@ -282,4 +283,4 @@
|
|||
Haven't found some strings? There's more at
|
||||
https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res
|
||||
-->
|
||||
</resources>
|
||||
</resources>
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
<string name="repeat_till">Atkārtot līdz</string>
|
||||
<string name="forever">Bezgalīgi</string>
|
||||
<string name="event_is_repeatable">Notikums ir atkārtojošs</string>
|
||||
<string name="task_is_repeatable">The task is repeatable</string>
|
||||
<string name="selection_contains_repetition">Atlasītajos ir atkārtojoši/periodiski notikumi</string>
|
||||
<string name="delete_one_only">Dzēst tikai šo atlasīto notikumu</string>
|
||||
<string name="delete_future_occurrences">Dzēst šo un visus turpmākos notikumus</string>
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
<string name="repeat_till">Gjenta til</string>
|
||||
<string name="forever">For alltid</string>
|
||||
<string name="event_is_repeatable">Hendelsen er repeterbar</string>
|
||||
<string name="task_is_repeatable">The task is repeatable</string>
|
||||
<string name="selection_contains_repetition">Markeringen inneholder gjentagende hendelser</string>
|
||||
<string name="delete_one_only">Slett bare den merkede forekomsten</string>
|
||||
<string name="delete_future_occurrences">Slett denne og alle framtidige forekomster</string>
|
||||
|
@ -279,4 +280,4 @@
|
|||
Haven't found some strings? There's more at
|
||||
https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res
|
||||
-->
|
||||
</resources>
|
||||
</resources>
|
||||
|
|
|
@ -55,6 +55,7 @@
|
|||
<string name="repeat_till">Herhalen tot</string>
|
||||
<string name="forever">Blijven herhalen</string>
|
||||
<string name="event_is_repeatable">De afspraak wordt herhaald</string>
|
||||
<string name="task_is_repeatable">The task is repeatable</string>
|
||||
<string name="selection_contains_repetition">De selectie bevat herhaalde afspraken</string>
|
||||
<string name="delete_one_only">Alleen huidige afspraak verwijderen</string>
|
||||
<string name="delete_future_occurrences">Deze afspraak en hierop volgende herhalingen verwijderen</string>
|
||||
|
@ -275,4 +276,4 @@
|
|||
Haven't found some strings? There's more at
|
||||
https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res
|
||||
-->
|
||||
</resources>
|
||||
</resources>
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
<string name="repeat_till">Powtarzaj do</string>
|
||||
<string name="forever">Zawsze</string>
|
||||
<string name="event_is_repeatable">Wydarzenie jest cykliczne</string>
|
||||
<string name="task_is_repeatable">The task is repeatable</string>
|
||||
<string name="selection_contains_repetition">Wybór zawiera powtarzające się wydarzenia</string>
|
||||
<string name="delete_one_only">Usuń tylko wybrane wystąpienie</string>
|
||||
<string name="delete_future_occurrences">Usuń to i wszystkie przyszłe wystąpienia</string>
|
||||
|
@ -285,4 +286,4 @@
|
|||
Haven't found some strings? There's more at
|
||||
https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res
|
||||
-->
|
||||
</resources>
|
||||
</resources>
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
<string name="repeat_till">Repetir até</string>
|
||||
<string name="forever">Eternamente</string>
|
||||
<string name="event_is_repeatable">O evento é repetitivo</string>
|
||||
<string name="task_is_repeatable">The task is repeatable</string>
|
||||
<string name="selection_contains_repetition">A seleção contém eventos recorrentes</string>
|
||||
<string name="delete_one_only">Apagar a ocorrência selecionada</string>
|
||||
<string name="delete_future_occurrences">Exclua essa e todas as ocorrências futuras</string>
|
||||
|
@ -280,4 +281,4 @@
|
|||
Não encontrou todas as cadeias a traduzir? Existem mais algumas em:
|
||||
https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res
|
||||
-->
|
||||
</resources>
|
||||
</resources>
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
<string name="repeat_till">Repetir até</string>
|
||||
<string name="forever">Eternamente</string>
|
||||
<string name="event_is_repeatable">O evento é recorrente</string>
|
||||
<string name="task_is_repeatable">The task is repeatable</string>
|
||||
<string name="selection_contains_repetition">A seleção contém eventos recorrentes</string>
|
||||
<string name="delete_one_only">Apagar a ocorrência selecionada</string>
|
||||
<string name="delete_future_occurrences">Apagar esta e todas as ocorrências futuras</string>
|
||||
|
@ -279,4 +280,4 @@
|
|||
Não encontrou todas as cadeias a traduzir? Existem mais algumas em:
|
||||
https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res
|
||||
-->
|
||||
</resources>
|
||||
</resources>
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
<string name="repeat_till">Repetă până pe</string>
|
||||
<string name="forever">Pentru totdeauna</string>
|
||||
<string name="event_is_repeatable">Evenimentul este repetabil</string>
|
||||
<string name="task_is_repeatable">The task is repeatable</string>
|
||||
<string name="selection_contains_repetition">Selecția conține evenimente repetitive</string>
|
||||
<string name="delete_one_only">Șterge numai evenimentul repetitiv selectat</string>
|
||||
<string name="delete_future_occurrences">Șterge acest și toate evenimentele repetitive viitoare</string>
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
<string name="repeat_till">Повторять до</string>
|
||||
<string name="forever">Бесконечно</string>
|
||||
<string name="event_is_repeatable">Это событие может повторяться</string>
|
||||
<string name="task_is_repeatable">The task is repeatable</string>
|
||||
<string name="selection_contains_repetition">В выбранном есть повторяющиеся события</string>
|
||||
<string name="delete_one_only">Удалить только это событие</string>
|
||||
<string name="delete_future_occurrences">Удалить это и все будущие события</string>
|
||||
|
@ -285,4 +286,4 @@
|
|||
Haven't found some strings? There's more at
|
||||
https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res
|
||||
-->
|
||||
</resources>
|
||||
</resources>
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
<string name="repeat_till">Opakovať do</string>
|
||||
<string name="forever">Navždy</string>
|
||||
<string name="event_is_repeatable">Udalosť je opakujúca sa</string>
|
||||
<string name="task_is_repeatable">Úloha je opakujúca sa</string>
|
||||
<string name="selection_contains_repetition">Výber obsahuje opakujúce sa udalosti</string>
|
||||
<string name="delete_one_only">Vymazať iba označené opakovania</string>
|
||||
<string name="delete_future_occurrences">Vymazať toto a všetky budúce opakovania</string>
|
||||
|
@ -282,4 +283,4 @@
|
|||
Haven't found some strings? There's more at
|
||||
https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res
|
||||
-->
|
||||
</resources>
|
||||
</resources>
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
<string name="repeat_till">Upprepa tills</string>
|
||||
<string name="forever">Alltid</string>
|
||||
<string name="event_is_repeatable">Händelsen är återkommande</string>
|
||||
<string name="task_is_repeatable">The task is repeatable</string>
|
||||
<string name="selection_contains_repetition">Markeringen innehåller återkommande händelser</string>
|
||||
<string name="delete_one_only">Ta bara bort den valda förekomsten</string>
|
||||
<string name="delete_future_occurrences">Ta bort denna och alla framtida förekomster</string>
|
||||
|
@ -279,4 +280,4 @@
|
|||
Haven't found some strings? There's more at
|
||||
https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res
|
||||
-->
|
||||
</resources>
|
||||
</resources>
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
<string name="repeat_till">Repeat till</string>
|
||||
<string name="forever">Forever</string>
|
||||
<string name="event_is_repeatable">The event is repeatable</string>
|
||||
<string name="task_is_repeatable">The task is repeatable</string>
|
||||
<string name="selection_contains_repetition">The selection contains repeating events</string>
|
||||
<string name="delete_one_only">Delete the selected occurrence only</string>
|
||||
<string name="delete_future_occurrences">Delete this and all future occurrences</string>
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
<string name="repeat_till">Şu kadar tekrarla:</string>
|
||||
<string name="forever">Sonsuza kadar</string>
|
||||
<string name="event_is_repeatable">Etkinlik tekrarlanabilir</string>
|
||||
<string name="task_is_repeatable">The task is repeatable</string>
|
||||
<string name="selection_contains_repetition">Seçim tekrarlanan etkinlikleri içeriyor</string>
|
||||
<string name="delete_one_only">Yalnızca seçilen etkinlikleri sil</string>
|
||||
<string name="delete_future_occurrences">Bu ve gelecekteki tüm etkinlikleri sil</string>
|
||||
|
@ -279,4 +280,4 @@
|
|||
Haven't found some strings? There's more at
|
||||
https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res
|
||||
-->
|
||||
</resources>
|
||||
</resources>
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
<string name="repeat_till">Повторювати до</string>
|
||||
<string name="forever">Безкінечно</string>
|
||||
<string name="event_is_repeatable">Ця подія є повторюваною</string>
|
||||
<string name="task_is_repeatable">The task is repeatable</string>
|
||||
<string name="selection_contains_repetition">Вибране містить повторювані події</string>
|
||||
<string name="delete_one_only">Видалити лише обране повторення</string>
|
||||
<string name="delete_future_occurrences">Видалити це і всі наступні повторення</string>
|
||||
|
@ -285,4 +286,4 @@
|
|||
Haven't found some strings? There's more at
|
||||
https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res
|
||||
-->
|
||||
</resources>
|
||||
</resources>
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
<string name="repeat_till">重复直到</string>
|
||||
<string name="forever">永远</string>
|
||||
<string name="event_is_repeatable">这是个重复活动</string>
|
||||
<string name="task_is_repeatable">The task is repeatable</string>
|
||||
<string name="selection_contains_repetition">选择的项目含有重复活动</string>
|
||||
<string name="delete_one_only">只删除选择的事件</string>
|
||||
<string name="delete_future_occurrences">删除这个及全部未来的事件</string>
|
||||
|
@ -276,4 +277,4 @@
|
|||
Haven't found some strings? There's more at
|
||||
https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res
|
||||
-->
|
||||
</resources>
|
||||
</resources>
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
<string name="repeat_till">重複直到</string>
|
||||
<string name="forever">永遠</string>
|
||||
<string name="event_is_repeatable">這是個重複活動</string>
|
||||
<string name="task_is_repeatable">The task is repeatable</string>
|
||||
<string name="selection_contains_repetition">選擇的項目含有重複活動</string>
|
||||
<string name="delete_one_only">只刪除選擇的事件</string>
|
||||
<string name="delete_future_occurrences">刪除這個及全部未來的事件</string>
|
||||
|
@ -276,4 +277,4 @@
|
|||
Haven't found some strings? There's more at
|
||||
https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res
|
||||
-->
|
||||
</resources>
|
||||
</resources>
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
<string name="repeat_till">重複直到</string>
|
||||
<string name="forever">永遠</string>
|
||||
<string name="event_is_repeatable">這是個重複活動</string>
|
||||
<string name="task_is_repeatable">The task is repeatable</string>
|
||||
<string name="selection_contains_repetition">選擇的項目含有重複活動</string>
|
||||
<string name="delete_one_only">只刪除選擇的事件</string>
|
||||
<string name="delete_future_occurrences">刪除這個及全部未來的事件</string>
|
||||
|
|
|
@ -57,6 +57,7 @@
|
|||
<string name="repeat_till">Repeat till</string>
|
||||
<string name="forever">Forever</string>
|
||||
<string name="event_is_repeatable">The event is repeatable</string>
|
||||
<string name="task_is_repeatable">The task is repeatable</string>
|
||||
<string name="selection_contains_repetition">The selection contains repeating events</string>
|
||||
<string name="delete_one_only">Delete the selected occurrence only</string>
|
||||
<string name="delete_future_occurrences">Delete this and all future occurrences</string>
|
||||
|
|
Loading…
Reference in New Issue