Merge pull request #20 from SimpleMobileTools/master

upd
This commit is contained in:
solokot
2019-03-14 23:30:26 +03:00
committed by GitHub
79 changed files with 1360 additions and 283 deletions

View File

@@ -1,6 +1,27 @@
Changelog Changelog
========== ==========
Version 6.3.2 *(2019-03-07)*
----------------------------
* Added a "Go to date" to most views for easy jumping between dates
* Added an app shortcut for creating new events quickly, from Android 7.1+
Version 6.3.1 *(2019-02-23)*
----------------------------
* Allow adding event reminders to birthdays/anniversaries
* Filled content description of some views to improve the UX of visually impaired people
* A few more stability and UX improvements here and there
Version 6.3.0 *(2019-02-14)*
----------------------------
* Allow setting default start time/duration/event type for new events
* Allow exporting/importing settings
* Fixed a glitch with repeating events older than from year 2001
* Fixed some glitches related to overlapping events on the monthly and weekly view
Version 6.2.2 *(2019-01-25)* Version 6.2.2 *(2019-01-25)*
---------------------------- ----------------------------

View File

@@ -15,8 +15,8 @@ The Contacts permission is used only at importing contact birthdays and annivers
This app is just one piece of a bigger series of apps. You can find the rest of them at https://www.simplemobiletools.com This app is just one piece of a bigger series of apps. You can find the rest of them at https://www.simplemobiletools.com
<a href='https://play.google.com/store/apps/details?id=com.simplemobiletools.calendar.pro'><img src='http://simplemobiletools.github.io/assets/public/google-play.png' alt='Get it on Google Play' height='45' /></a> <a href='https://play.google.com/store/apps/details?id=com.simplemobiletools.calendar.pro'><img src='https://simplemobiletools.com/assets/images/google-play.png' alt='Get it on Google Play' height='45' /></a>
<a href='https://f-droid.org/packages/com.simplemobiletools.calendar.pro'><img src='http://simplemobiletools.github.io/assets/public/f-droid.png' alt='Get it on F-Droid' height='45' /></a> <a href='https://f-droid.org/packages/com.simplemobiletools.calendar.pro'><img src='https://simplemobiletools.com/assets/images/f-droid.png' alt='Get it on F-Droid' height='45' /></a>
<div style="display:flex;"> <div style="display:flex;">
<img alt="App image" src="fastlane/metadata/android/en-US/images/phoneScreenshots/app.png" width="30%"> <img alt="App image" src="fastlane/metadata/android/en-US/images/phoneScreenshots/app.png" width="30%">

View File

@@ -2,6 +2,7 @@ apply plugin: 'com.android.application'
apply plugin: 'kotlin-android' apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions' apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt' apply plugin: 'kotlin-kapt'
apply plugin: 'de.timfreiheit.resourceplaceholders'
def keystorePropertiesFile = rootProject.file("keystore.properties") def keystorePropertiesFile = rootProject.file("keystore.properties")
def keystoreProperties = new Properties() def keystoreProperties = new Properties()
@@ -15,8 +16,8 @@ android {
applicationId "com.simplemobiletools.calendar.pro" applicationId "com.simplemobiletools.calendar.pro"
minSdkVersion 21 minSdkVersion 21
targetSdkVersion 28 targetSdkVersion 28
versionCode 142 versionCode 145
versionName "6.2.2" versionName "6.3.2"
multiDexEnabled true multiDexEnabled true
setProperty("archivesBaseName", "calendar") setProperty("archivesBaseName", "calendar")
} }
@@ -49,12 +50,17 @@ android {
checkReleaseBuilds false checkReleaseBuilds false
abortOnError false abortOnError false
} }
resourcePlaceholders {
files = ['xml/shortcuts.xml']
}
} }
dependencies { dependencies {
implementation 'com.simplemobiletools:commons:5.7.7' implementation 'com.simplemobiletools:commons:5.10.10'
implementation 'joda-time:joda-time:2.10.1' implementation 'joda-time:joda-time:2.10.1'
implementation 'androidx.multidex:multidex:2.0.1' implementation 'androidx.multidex:multidex:2.0.1'
implementation 'androidx.constraintlayout:constraintlayout:2.0.0-alpha3'
kapt 'androidx.room:room-compiler:2.0.0' kapt 'androidx.room:room-compiler:2.0.0'
implementation 'androidx.room:room-runtime:2.0.0' implementation 'androidx.room:room-runtime:2.0.0'

View File

@@ -16,14 +16,18 @@
android:name="android.permission.USE_FINGERPRINT" android:name="android.permission.USE_FINGERPRINT"
tools:node="remove"/> tools:node="remove"/>
<uses-feature
android:name="android.hardware.faketouch"
android:required="false"/>
<application <application
android:name=".App" android:name=".App"
android:allowBackup="true" android:allowBackup="true"
android:icon="@mipmap/ic_launcher" android:icon="@mipmap/ic_launcher"
android:label="@string/app_launcher_name" android:label="@string/app_launcher_name"
android:roundIcon="@mipmap/ic_launcher" android:roundIcon="@mipmap/ic_launcher"
android:theme="@style/AppTheme" android:supportsRtl="true"
android:supportsRtl="true"> android:theme="@style/AppTheme">
<activity <activity
android:name=".activities.SplashActivity" android:name=".activities.SplashActivity"

View File

@@ -3,30 +3,41 @@ package com.simplemobiletools.calendar.pro.activities
import android.app.DatePickerDialog import android.app.DatePickerDialog
import android.app.TimePickerDialog import android.app.TimePickerDialog
import android.content.Intent import android.content.Intent
import android.database.Cursor
import android.net.Uri import android.net.Uri
import android.os.Bundle import android.os.Bundle
import android.provider.CalendarContract
import android.provider.ContactsContract
import android.text.TextUtils
import android.text.method.LinkMovementMethod import android.text.method.LinkMovementMethod
import android.view.Menu import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import android.view.WindowManager import android.view.WindowManager
import android.widget.EditText
import android.widget.ImageView
import android.widget.RelativeLayout
import androidx.core.app.NotificationManagerCompat import androidx.core.app.NotificationManagerCompat
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import com.simplemobiletools.calendar.pro.R import com.simplemobiletools.calendar.pro.R
import com.simplemobiletools.calendar.pro.adapters.AutoCompleteTextViewAdapter
import com.simplemobiletools.calendar.pro.dialogs.* import com.simplemobiletools.calendar.pro.dialogs.*
import com.simplemobiletools.calendar.pro.extensions.* import com.simplemobiletools.calendar.pro.extensions.*
import com.simplemobiletools.calendar.pro.helpers.* import com.simplemobiletools.calendar.pro.helpers.*
import com.simplemobiletools.calendar.pro.helpers.Formatter import com.simplemobiletools.calendar.pro.helpers.Formatter
import com.simplemobiletools.calendar.pro.models.CalDAVCalendar import com.simplemobiletools.calendar.pro.models.*
import com.simplemobiletools.calendar.pro.models.Event
import com.simplemobiletools.calendar.pro.models.EventType
import com.simplemobiletools.commons.dialogs.ConfirmationDialog import com.simplemobiletools.commons.dialogs.ConfirmationDialog
import com.simplemobiletools.commons.dialogs.RadioGroupDialog import com.simplemobiletools.commons.dialogs.RadioGroupDialog
import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.* import com.simplemobiletools.commons.helpers.*
import com.simplemobiletools.commons.models.RadioItem import com.simplemobiletools.commons.models.RadioItem
import kotlinx.android.synthetic.main.activity_event.* import kotlinx.android.synthetic.main.activity_event.*
import kotlinx.android.synthetic.main.activity_event.view.*
import kotlinx.android.synthetic.main.item_attendee.view.*
import org.joda.time.DateTime import org.joda.time.DateTime
import java.util.* import java.util.*
import java.util.regex.Pattern import java.util.regex.Pattern
import kotlin.collections.ArrayList
class EventActivity : SimpleActivity() { class EventActivity : SimpleActivity() {
private val LAT_LON_PATTERN = "^[-+]?([1-8]?\\d(\\.\\d+)?|90(\\.0+)?)([,;])\\s*[-+]?(180(\\.0+)?|((1[0-7]\\d)|([1-9]?\\d))(\\.\\d+)?)\$" private val LAT_LON_PATTERN = "^[-+]?([1-8]?\\d(\\.\\d+)?|90(\\.0+)?)([,;])\\s*[-+]?(180(\\.0+)?|((1[0-7]\\d)|([1-9]?\\d))(\\.\\d+)?)\$"
@@ -36,15 +47,22 @@ class EventActivity : SimpleActivity() {
private val REMINDER_1_MINUTES = "REMINDER_1_MINUTES" private val REMINDER_1_MINUTES = "REMINDER_1_MINUTES"
private val REMINDER_2_MINUTES = "REMINDER_2_MINUTES" private val REMINDER_2_MINUTES = "REMINDER_2_MINUTES"
private val REMINDER_3_MINUTES = "REMINDER_3_MINUTES" private val REMINDER_3_MINUTES = "REMINDER_3_MINUTES"
private val REMINDER_1_TYPE = "REMINDER_1_TYPE"
private val REMINDER_2_TYPE = "REMINDER_2_TYPE"
private val REMINDER_3_TYPE = "REMINDER_3_TYPE"
private val REPEAT_INTERVAL = "REPEAT_INTERVAL" private val REPEAT_INTERVAL = "REPEAT_INTERVAL"
private val REPEAT_LIMIT = "REPEAT_LIMIT" private val REPEAT_LIMIT = "REPEAT_LIMIT"
private val REPEAT_RULE = "REPEAT_RULE" private val REPEAT_RULE = "REPEAT_RULE"
private val ATTENDEES = "ATTENDEES"
private val EVENT_TYPE_ID = "EVENT_TYPE_ID" private val EVENT_TYPE_ID = "EVENT_TYPE_ID"
private val EVENT_CALENDAR_ID = "EVENT_CALENDAR_ID" private val EVENT_CALENDAR_ID = "EVENT_CALENDAR_ID"
private var mReminder1Minutes = 0 private var mReminder1Minutes = REMINDER_OFF
private var mReminder2Minutes = 0 private var mReminder2Minutes = REMINDER_OFF
private var mReminder3Minutes = 0 private var mReminder3Minutes = REMINDER_OFF
private var mReminder1Type = REMINDER_NOTIFICATION
private var mReminder2Type = REMINDER_NOTIFICATION
private var mReminder3Type = REMINDER_NOTIFICATION
private var mRepeatInterval = 0 private var mRepeatInterval = 0
private var mRepeatLimit = 0L private var mRepeatLimit = 0L
private var mRepeatRule = 0 private var mRepeatRule = 0
@@ -52,7 +70,11 @@ class EventActivity : SimpleActivity() {
private var mDialogTheme = 0 private var mDialogTheme = 0
private var mEventOccurrenceTS = 0L private var mEventOccurrenceTS = 0L
private var mEventCalendarId = STORED_LOCALLY_ONLY private var mEventCalendarId = STORED_LOCALLY_ONLY
private var wasActivityInitialized = false private var mWasActivityInitialized = false
private var mWasContactsPermissionChecked = false
private var mAttendees = ArrayList<Attendee>()
private var mAttendeeViews = ArrayList<EditText>()
private var mAvailableContacts = ArrayList<Attendee>()
private lateinit var mEventStartDateTime: DateTime private lateinit var mEventStartDateTime: DateTime
private lateinit var mEventEndDateTime: DateTime private lateinit var mEventEndDateTime: DateTime
@@ -65,6 +87,7 @@ class EventActivity : SimpleActivity() {
supportActionBar?.setHomeAsUpIndicator(R.drawable.ic_cross) supportActionBar?.setHomeAsUpIndicator(R.drawable.ic_cross)
val intent = intent ?: return val intent = intent ?: return
mDialogTheme = getDialogTheme() mDialogTheme = getDialogTheme()
mWasContactsPermissionChecked = hasPermission(PERMISSION_READ_CONTACTS)
val eventId = intent.getLongExtra(EVENT_ID, 0L) val eventId = intent.getLongExtra(EVENT_ID, 0L)
Thread { Thread {
@@ -78,6 +101,7 @@ class EventActivity : SimpleActivity() {
runOnUiThread { runOnUiThread {
gotEvent(savedInstanceState, localEventType, event) gotEvent(savedInstanceState, localEventType, event)
} }
fillAvailableContacts()
}.start() }.start()
} }
@@ -117,6 +141,7 @@ class EventActivity : SimpleActivity() {
updateTexts() updateTexts()
updateEventType() updateEventType()
updateCalDAVCalendar() updateCalDAVCalendar()
updateAttendees()
} }
event_show_on_map.setOnClickListener { showOnMap() } event_show_on_map.setOnClickListener { showOnMap() }
@@ -146,19 +171,41 @@ class EventActivity : SimpleActivity() {
event_reminder_2.setOnClickListener { showReminder2Dialog() } event_reminder_2.setOnClickListener { showReminder2Dialog() }
event_reminder_3.setOnClickListener { showReminder3Dialog() } event_reminder_3.setOnClickListener { showReminder3Dialog() }
event_type_holder.setOnClickListener { showEventTypeDialog() } event_reminder_1_type.setOnClickListener {
showReminderTypePicker(mReminder1Type) {
mReminder1Type = it
updateReminderTypeImage(event_reminder_1_type, Reminder(mReminder1Minutes, mReminder1Type))
}
}
if (mEvent.flags and FLAG_ALL_DAY != 0) event_reminder_2_type.setOnClickListener {
event_all_day.toggle() showReminderTypePicker(mReminder2Type) {
mReminder2Type = it
updateReminderTypeImage(event_reminder_2_type, Reminder(mReminder2Minutes, mReminder2Type))
}
}
event_reminder_3_type.setOnClickListener {
showReminderTypePicker(mReminder3Type) {
mReminder3Type = it
updateReminderTypeImage(event_reminder_3_type, Reminder(mReminder3Minutes, mReminder3Type))
}
}
event_type_holder.setOnClickListener { showEventTypeDialog() }
event_all_day.apply {
isChecked = mEvent.flags and FLAG_ALL_DAY != 0
jumpDrawablesToCurrentState()
}
updateTextColors(event_scrollview) updateTextColors(event_scrollview)
updateIconColors() updateIconColors()
wasActivityInitialized = true mWasActivityInitialized = true
} }
override fun onCreateOptionsMenu(menu: Menu): Boolean { override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.menu_event, menu) menuInflater.inflate(R.menu.menu_event, menu)
if (wasActivityInitialized) { if (mWasActivityInitialized) {
menu.findItem(R.id.delete).isVisible = mEvent.id != null menu.findItem(R.id.delete).isVisible = mEvent.id != null
menu.findItem(R.id.share).isVisible = mEvent.id != null menu.findItem(R.id.share).isVisible = mEvent.id != null
menu.findItem(R.id.duplicate).isVisible = mEvent.id != null menu.findItem(R.id.duplicate).isVisible = mEvent.id != null
@@ -179,7 +226,7 @@ class EventActivity : SimpleActivity() {
override fun onSaveInstanceState(outState: Bundle) { override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState) super.onSaveInstanceState(outState)
if (!wasActivityInitialized) { if (!mWasActivityInitialized) {
return return
} }
@@ -192,10 +239,16 @@ class EventActivity : SimpleActivity() {
putInt(REMINDER_2_MINUTES, mReminder2Minutes) putInt(REMINDER_2_MINUTES, mReminder2Minutes)
putInt(REMINDER_3_MINUTES, mReminder3Minutes) putInt(REMINDER_3_MINUTES, mReminder3Minutes)
putInt(REMINDER_1_TYPE, mReminder1Type)
putInt(REMINDER_2_TYPE, mReminder2Type)
putInt(REMINDER_3_TYPE, mReminder3Type)
putInt(REPEAT_INTERVAL, mRepeatInterval) putInt(REPEAT_INTERVAL, mRepeatInterval)
putInt(REPEAT_RULE, mRepeatRule) putInt(REPEAT_RULE, mRepeatRule)
putLong(REPEAT_LIMIT, mRepeatLimit) putLong(REPEAT_LIMIT, mRepeatLimit)
putString(ATTENDEES, getAllAttendees())
putLong(EVENT_TYPE_ID, mEventTypeId) putLong(EVENT_TYPE_ID, mEventTypeId)
putInt(EVENT_CALENDAR_ID, mEventCalendarId) putInt(EVENT_CALENDAR_ID, mEventCalendarId)
} }
@@ -217,10 +270,17 @@ class EventActivity : SimpleActivity() {
mReminder2Minutes = getInt(REMINDER_2_MINUTES) mReminder2Minutes = getInt(REMINDER_2_MINUTES)
mReminder3Minutes = getInt(REMINDER_3_MINUTES) mReminder3Minutes = getInt(REMINDER_3_MINUTES)
mReminder1Type = getInt(REMINDER_1_TYPE)
mReminder2Type = getInt(REMINDER_2_TYPE)
mReminder3Type = getInt(REMINDER_3_TYPE)
mRepeatInterval = getInt(REPEAT_INTERVAL) mRepeatInterval = getInt(REPEAT_INTERVAL)
mRepeatRule = getInt(REPEAT_RULE) mRepeatRule = getInt(REPEAT_RULE)
mRepeatLimit = getLong(REPEAT_LIMIT) mRepeatLimit = getLong(REPEAT_LIMIT)
mAttendees = Gson().fromJson<ArrayList<Attendee>>(getString(ATTENDEES), object : TypeToken<List<Attendee>>() {}.type)
?: ArrayList()
mEventTypeId = getLong(EVENT_TYPE_ID) mEventTypeId = getLong(EVENT_TYPE_ID)
mEventCalendarId = getInt(EVENT_CALENDAR_ID) mEventCalendarId = getInt(EVENT_CALENDAR_ID)
} }
@@ -230,6 +290,7 @@ class EventActivity : SimpleActivity() {
updateTexts() updateTexts()
updateEventType() updateEventType()
updateCalDAVCalendar() updateCalDAVCalendar()
updateAttendees()
} }
private fun updateTexts() { private fun updateTexts() {
@@ -237,6 +298,7 @@ class EventActivity : SimpleActivity() {
checkReminderTexts() checkReminderTexts()
updateStartTexts() updateStartTexts()
updateEndTexts() updateEndTexts()
updateAttendeesVisibility()
} }
private fun setupEditEvent() { private fun setupEditEvent() {
@@ -253,11 +315,15 @@ class EventActivity : SimpleActivity() {
mReminder1Minutes = mEvent.reminder1Minutes mReminder1Minutes = mEvent.reminder1Minutes
mReminder2Minutes = mEvent.reminder2Minutes mReminder2Minutes = mEvent.reminder2Minutes
mReminder3Minutes = mEvent.reminder3Minutes mReminder3Minutes = mEvent.reminder3Minutes
mReminder1Type = mEvent.reminder1Type
mReminder2Type = mEvent.reminder2Type
mReminder3Type = mEvent.reminder3Type
mRepeatInterval = mEvent.repeatInterval mRepeatInterval = mEvent.repeatInterval
mRepeatLimit = mEvent.repeatLimit mRepeatLimit = mEvent.repeatLimit
mRepeatRule = mEvent.repeatRule mRepeatRule = mEvent.repeatRule
mEventTypeId = mEvent.eventType mEventTypeId = mEvent.eventType
mEventCalendarId = mEvent.getCalDAVCalendarId() mEventCalendarId = mEvent.getCalDAVCalendarId()
mAttendees = Gson().fromJson<ArrayList<Attendee>>(mEvent.attendees, object : TypeToken<List<Attendee>>() {}.type) ?: ArrayList()
checkRepeatTexts(mRepeatInterval) checkRepeatTexts(mRepeatInterval)
} }
@@ -558,6 +624,7 @@ class EventActivity : SimpleActivity() {
updateReminder1Text() updateReminder1Text()
updateReminder2Text() updateReminder2Text()
updateReminder3Text() updateReminder3Text()
updateReminderTypeImages()
} }
private fun updateReminder1Text() { private fun updateReminder1Text() {
@@ -590,6 +657,36 @@ class EventActivity : SimpleActivity() {
} }
} }
private fun showReminderTypePicker(currentValue: Int, callback: (Int) -> Unit) {
val items = arrayListOf(
RadioItem(REMINDER_NOTIFICATION, getString(R.string.notification)),
RadioItem(REMINDER_EMAIL, getString(R.string.email))
)
RadioGroupDialog(this, items, currentValue) {
callback(it as Int)
}
}
private fun updateReminderTypeImages() {
updateReminderTypeImage(event_reminder_1_type, Reminder(mReminder1Minutes, mReminder1Type))
updateReminderTypeImage(event_reminder_2_type, Reminder(mReminder2Minutes, mReminder2Type))
updateReminderTypeImage(event_reminder_3_type, Reminder(mReminder3Minutes, mReminder3Type))
}
private fun updateAttendeesVisibility() {
val isSyncedEvent = mEventCalendarId != STORED_LOCALLY_ONLY
event_attendees_image.beVisibleIf(isSyncedEvent)
event_attendees_holder.beVisibleIf(isSyncedEvent)
event_attendees_divider.beVisibleIf(isSyncedEvent)
}
private fun updateReminderTypeImage(view: ImageView, reminder: Reminder) {
view.beVisibleIf(reminder.minutes != REMINDER_OFF && mEventCalendarId != STORED_LOCALLY_ONLY)
val drawable = if (reminder.type == REMINDER_NOTIFICATION) R.drawable.ic_bell else R.drawable.ic_email
val icon = resources.getColoredDrawableWithColor(drawable, config.textColor)
view.setImageDrawable(icon)
}
private fun updateRepetitionText() { private fun updateRepetitionText() {
event_repetition.text = getRepetitionText(mRepeatInterval) event_repetition.text = getRepetitionText(mRepeatInterval)
} }
@@ -627,6 +724,8 @@ class EventActivity : SimpleActivity() {
mEventCalendarId = it mEventCalendarId = it
config.lastUsedCaldavCalendarId = it config.lastUsedCaldavCalendarId = it
updateCurrentCalendarInfo(getCalendarWithId(calendars, it)) updateCurrentCalendarInfo(getCalendarWithId(calendars, it))
updateReminderTypeImages()
updateAttendeesVisibility()
} }
} }
} else { } else {
@@ -765,16 +864,26 @@ class EventActivity : SimpleActivity() {
"$CALDAV-$mEventCalendarId" "$CALDAV-$mEventCalendarId"
} }
val reminders = sortedSetOf(mReminder1Minutes, mReminder2Minutes, mReminder3Minutes).filter { it != REMINDER_OFF } var reminders = arrayListOf(
val reminder1 = reminders.getOrElse(0) { REMINDER_OFF } Reminder(mReminder1Minutes, mReminder1Type),
val reminder2 = reminders.getOrElse(1) { REMINDER_OFF } Reminder(mReminder2Minutes, mReminder2Type),
val reminder3 = reminders.getOrElse(2) { REMINDER_OFF } Reminder(mReminder3Minutes, mReminder3Type)
)
reminders = reminders.filter { it.minutes != REMINDER_OFF }.sortedBy { it.minutes }.toMutableList() as ArrayList<Reminder>
val reminder1 = reminders.getOrNull(0) ?: Reminder(REMINDER_OFF, REMINDER_NOTIFICATION)
val reminder2 = reminders.getOrNull(1) ?: Reminder(REMINDER_OFF, REMINDER_NOTIFICATION)
val reminder3 = reminders.getOrNull(2) ?: Reminder(REMINDER_OFF, REMINDER_NOTIFICATION)
mReminder1Type = if (mEventCalendarId == STORED_LOCALLY_ONLY) REMINDER_NOTIFICATION else reminder1.type
mReminder2Type = if (mEventCalendarId == STORED_LOCALLY_ONLY) REMINDER_NOTIFICATION else reminder2.type
mReminder3Type = if (mEventCalendarId == STORED_LOCALLY_ONLY) REMINDER_NOTIFICATION else reminder3.type
config.apply { config.apply {
if (usePreviousEventReminders) { if (usePreviousEventReminders) {
lastEventReminderMinutes1 = reminder1 lastEventReminderMinutes1 = reminder1.minutes
lastEventReminderMinutes2 = reminder2 lastEventReminderMinutes2 = reminder2.minutes
lastEventReminderMinutes3 = reminder3 lastEventReminderMinutes3 = reminder3.minutes
} }
} }
@@ -783,14 +892,18 @@ class EventActivity : SimpleActivity() {
endTS = newEndTS endTS = newEndTS
title = newTitle title = newTitle
description = event_description.value description = event_description.value
reminder1Minutes = reminder1 reminder1Minutes = reminder1.minutes
reminder2Minutes = reminder2 reminder2Minutes = reminder2.minutes
reminder3Minutes = reminder3 reminder3Minutes = reminder3.minutes
reminder1Type = mReminder1Type
reminder2Type = mReminder2Type
reminder3Type = mReminder3Type
repeatInterval = mRepeatInterval repeatInterval = mRepeatInterval
importId = newImportId importId = newImportId
flags = mEvent.flags.addBitIf(event_all_day.isChecked, FLAG_ALL_DAY) flags = mEvent.flags.addBitIf(event_all_day.isChecked, FLAG_ALL_DAY)
repeatLimit = if (repeatInterval == 0) 0 else mRepeatLimit repeatLimit = if (repeatInterval == 0) 0 else mRepeatLimit
repeatRule = mRepeatRule repeatRule = mRepeatRule
attendees = if (mEventCalendarId == STORED_LOCALLY_ONLY) "" else getAllAttendees()
eventType = newEventType eventType = newEventType
lastUpdated = System.currentTimeMillis() lastUpdated = System.currentTimeMillis()
source = newSource source = newSource
@@ -810,7 +923,7 @@ class EventActivity : SimpleActivity() {
if (mEvent.id == null || mEvent.id == null) { if (mEvent.id == null || mEvent.id == null) {
eventsHelper.insertEvent(mEvent, true, true) { eventsHelper.insertEvent(mEvent, true, true) {
if (DateTime.now().isAfter(mEventStartDateTime.millis)) { if (DateTime.now().isAfter(mEventStartDateTime.millis)) {
if (mEvent.repeatInterval == 0 && mEvent.getReminders().isNotEmpty()) { if (mEvent.repeatInterval == 0 && mEvent.getReminders().any { it.type == REMINDER_NOTIFICATION }) {
notifyEvent(mEvent) notifyEvent(mEvent)
} }
} }
@@ -1006,6 +1119,154 @@ class EventActivity : SimpleActivity() {
} }
} }
private fun fillAvailableContacts() {
mAvailableContacts = getEmails()
val names = getNames()
mAvailableContacts.forEach {
val contactId = it.contactId
val contact = names.firstOrNull { it.contactId == contactId }
val name = contact?.name
if (name != null) {
it.name = name
}
val photoUri = contact?.photoUri
if (photoUri != null) {
it.photoUri = photoUri
}
}
}
private fun updateAttendees() {
mAttendees.forEach {
addAttendee(it.getPublicName())
}
addAttendee()
val imageHeight = event_repetition_image.height
if (imageHeight > 0) {
event_attendees_image.layoutParams.height = imageHeight
} else {
event_repetition_image.onGlobalLayout {
event_attendees_image.layoutParams.height = event_repetition_image.height
}
}
}
private fun addAttendee(value: String? = null) {
val attendeeHolder = layoutInflater.inflate(R.layout.item_attendee, event_attendees_holder, false) as RelativeLayout
mAttendeeViews.add(attendeeHolder.event_attendee)
attendeeHolder.event_attendee.onTextChangeListener {
if (mWasContactsPermissionChecked && value == null) {
checkNewAttendeeField(value)
} else {
handlePermission(PERMISSION_READ_CONTACTS) {
checkNewAttendeeField(value)
mWasContactsPermissionChecked = true
}
}
}
event_attendees_holder.addView(attendeeHolder)
attendeeHolder.event_attendee.setColors(config.textColor, getAdjustedPrimaryColor(), config.backgroundColor)
if (value != null) {
attendeeHolder.event_attendee.setText(value)
}
val adapter = AutoCompleteTextViewAdapter(this, mAvailableContacts)
attendeeHolder.event_attendee.setAdapter(adapter)
attendeeHolder.event_attendee.setOnItemClickListener { parent, view, position, id ->
val currAttendees = (attendeeHolder.event_attendee.adapter as AutoCompleteTextViewAdapter).resultList
val selectedAttendee = currAttendees[position]
}
}
private fun checkNewAttendeeField(value: String?) {
if (value == null && mAttendeeViews.none { it.value.isEmpty() }) {
addAttendee()
}
}
private fun getAllAttendees(): String {
val attendeeEmails = mAttendeeViews.map { it.value }.filter { it.isNotEmpty() }.toMutableList() as ArrayList<String>
val attendees = ArrayList<Attendee>()
attendeeEmails.mapTo(attendees) {
Attendee(0, "", it, CalendarContract.Attendees.ATTENDEE_STATUS_INVITED, "")
}
return Gson().toJson(attendees)
}
private fun getNames(): List<Attendee> {
val contacts = ArrayList<Attendee>()
val uri = ContactsContract.Data.CONTENT_URI
val projection = arrayOf(
ContactsContract.Data.CONTACT_ID,
ContactsContract.CommonDataKinds.StructuredName.PREFIX,
ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME,
ContactsContract.CommonDataKinds.StructuredName.MIDDLE_NAME,
ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME,
ContactsContract.CommonDataKinds.StructuredName.SUFFIX,
ContactsContract.CommonDataKinds.StructuredName.PHOTO_THUMBNAIL_URI)
val selection = "${ContactsContract.Data.MIMETYPE} = ?"
val selectionArgs = arrayOf(ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
var cursor: Cursor? = null
try {
cursor = contentResolver.query(uri, projection, selection, selectionArgs, null)
if (cursor?.moveToFirst() == true) {
do {
val id = cursor.getIntValue(ContactsContract.Data.CONTACT_ID)
val prefix = cursor.getStringValue(ContactsContract.CommonDataKinds.StructuredName.PREFIX) ?: ""
val firstName = cursor.getStringValue(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME) ?: ""
val middleName = cursor.getStringValue(ContactsContract.CommonDataKinds.StructuredName.MIDDLE_NAME) ?: ""
val surname = cursor.getStringValue(ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME) ?: ""
val suffix = cursor.getStringValue(ContactsContract.CommonDataKinds.StructuredName.SUFFIX) ?: ""
val photoUri = cursor.getStringValue(ContactsContract.CommonDataKinds.StructuredName.PHOTO_THUMBNAIL_URI) ?: ""
val names = arrayListOf(prefix, firstName, middleName, surname, suffix).filter { it.trim().isNotEmpty() }
val fullName = TextUtils.join("", names)
if (fullName.isNotEmpty() || photoUri.isNotEmpty()) {
val contact = Attendee(id, fullName, "", 0, photoUri)
contacts.add(contact)
}
} while (cursor.moveToNext())
}
} catch (ignored: Exception) {
} finally {
cursor?.close()
}
return contacts
}
private fun getEmails(): ArrayList<Attendee> {
val contacts = ArrayList<Attendee>()
val uri = ContactsContract.CommonDataKinds.Email.CONTENT_URI
val projection = arrayOf(
ContactsContract.Data.CONTACT_ID,
ContactsContract.CommonDataKinds.Email.DATA
)
var cursor: Cursor? = null
try {
cursor = contentResolver.query(uri, projection, null, null, null)
if (cursor?.moveToFirst() == true) {
do {
val id = cursor.getIntValue(ContactsContract.Data.CONTACT_ID)
val email = cursor.getStringValue(ContactsContract.CommonDataKinds.Email.DATA) ?: continue
val contact = Attendee(id, "", email, 0, "")
contacts.add(contact)
} while (cursor.moveToNext())
}
} catch (ignored: Exception) {
} finally {
cursor?.close()
}
return contacts
}
private fun updateIconColors() { private fun updateIconColors() {
val textColor = config.textColor val textColor = config.textColor
event_time_image.applyColorFilter(textColor) event_time_image.applyColorFilter(textColor)
@@ -1014,5 +1275,9 @@ class EventActivity : SimpleActivity() {
event_type_image.applyColorFilter(textColor) event_type_image.applyColorFilter(textColor)
event_caldav_calendar_image.applyColorFilter(textColor) event_caldav_calendar_image.applyColorFilter(textColor)
event_show_on_map.applyColorFilter(getAdjustedPrimaryColor()) event_show_on_map.applyColorFilter(getAdjustedPrimaryColor())
event_reminder_1_type.applyColorFilter(textColor)
event_reminder_2_type.applyColorFilter(textColor)
event_reminder_3_type.applyColorFilter(textColor)
event_attendees_image.applyColorFilter(textColor)
} }
} }

View File

@@ -1,11 +1,16 @@
package com.simplemobiletools.calendar.pro.activities package com.simplemobiletools.calendar.pro.activities
import android.annotation.SuppressLint
import android.app.SearchManager import android.app.SearchManager
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.pm.ActivityInfo import android.content.pm.ActivityInfo
import android.content.pm.ShortcutInfo
import android.content.pm.ShortcutManager
import android.database.Cursor import android.database.Cursor
import android.graphics.drawable.ColorDrawable import android.graphics.drawable.ColorDrawable
import android.graphics.drawable.Icon
import android.graphics.drawable.LayerDrawable
import android.net.Uri import android.net.Uri
import android.os.Bundle import android.os.Bundle
import android.provider.ContactsContract import android.provider.ContactsContract
@@ -21,6 +26,7 @@ import com.simplemobiletools.calendar.pro.databases.EventsDatabase
import com.simplemobiletools.calendar.pro.dialogs.ExportEventsDialog import com.simplemobiletools.calendar.pro.dialogs.ExportEventsDialog
import com.simplemobiletools.calendar.pro.dialogs.FilterEventTypesDialog import com.simplemobiletools.calendar.pro.dialogs.FilterEventTypesDialog
import com.simplemobiletools.calendar.pro.dialogs.ImportEventsDialog import com.simplemobiletools.calendar.pro.dialogs.ImportEventsDialog
import com.simplemobiletools.calendar.pro.dialogs.SetRemindersDialog
import com.simplemobiletools.calendar.pro.extensions.* import com.simplemobiletools.calendar.pro.extensions.*
import com.simplemobiletools.calendar.pro.fragments.* import com.simplemobiletools.calendar.pro.fragments.*
import com.simplemobiletools.calendar.pro.helpers.* import com.simplemobiletools.calendar.pro.helpers.*
@@ -129,6 +135,7 @@ class MainActivity : SimpleActivity(), RefreshRecyclerViewListener {
calendar_fab.setColors(config.textColor, getAdjustedPrimaryColor(), config.backgroundColor) calendar_fab.setColors(config.textColor, getAdjustedPrimaryColor(), config.backgroundColor)
search_holder.background = ColorDrawable(config.backgroundColor) search_holder.background = ColorDrawable(config.backgroundColor)
checkSwipeRefreshAvailability() checkSwipeRefreshAvailability()
checkShortcuts()
} }
override fun onPause() { override fun onPause() {
@@ -154,6 +161,7 @@ class MainActivity : SimpleActivity(), RefreshRecyclerViewListener {
goToTodayButton = findItem(R.id.go_to_today) goToTodayButton = findItem(R.id.go_to_today)
findItem(R.id.filter).isVisible = mShouldFilterBeVisible findItem(R.id.filter).isVisible = mShouldFilterBeVisible
findItem(R.id.go_to_today).isVisible = shouldGoToTodayBeVisible && config.storedView != EVENTS_LIST_VIEW findItem(R.id.go_to_today).isVisible = shouldGoToTodayBeVisible && config.storedView != EVENTS_LIST_VIEW
findItem(R.id.go_to_date).isVisible = config.storedView != EVENTS_LIST_VIEW
} }
setupSearch(menu) setupSearch(menu)
@@ -172,6 +180,7 @@ class MainActivity : SimpleActivity(), RefreshRecyclerViewListener {
when (item.itemId) { when (item.itemId) {
R.id.change_view -> showViewDialog() R.id.change_view -> showViewDialog()
R.id.go_to_today -> goToToday() R.id.go_to_today -> goToToday()
R.id.go_to_date -> showGoToDateDialog()
R.id.filter -> showFilterDialog() R.id.filter -> showFilterDialog()
R.id.refresh_caldav_calendars -> refreshCalDAVCalendars(true) R.id.refresh_caldav_calendars -> refreshCalDAVCalendars(true)
R.id.add_holidays -> addHolidays() R.id.add_holidays -> addHolidays()
@@ -256,6 +265,33 @@ class MainActivity : SimpleActivity(), RefreshRecyclerViewListener {
mSearchMenuItem?.collapseActionView() mSearchMenuItem?.collapseActionView()
} }
@SuppressLint("NewApi")
private fun checkShortcuts() {
val appIconColor = config.appIconColor
if (isNougatMR1Plus() && config.lastHandledShortcutColor != appIconColor) {
val newEvent = getString(R.string.new_event)
val manager = getSystemService(ShortcutManager::class.java)
val drawable = resources.getDrawable(R.drawable.shortcut_plus)
(drawable as LayerDrawable).findDrawableByLayerId(R.id.shortcut_plus_background).applyColorFilter(appIconColor)
val bmp = drawable.convertToBitmap()
val intent = Intent(this, SplashActivity::class.java)
intent.action = SHORTCUT_NEW_EVENT
val shortcut = ShortcutInfo.Builder(this, "new_event")
.setShortLabel(newEvent)
.setLongLabel(newEvent)
.setIcon(Icon.createWithBitmap(bmp))
.setIntent(intent)
.build()
try {
manager.dynamicShortcuts = Arrays.asList(shortcut)
config.lastHandledShortcutColor = appIconColor
} catch (ignored: Exception) {
}
}
}
private fun checkIsOpenIntent(): Boolean { private fun checkIsOpenIntent(): Boolean {
val dayCodeToOpen = intent.getStringExtra(DAY_CODE) ?: "" val dayCodeToOpen = intent.getStringExtra(DAY_CODE) ?: ""
val viewToOpen = intent.getIntExtra(VIEW_TO_OPEN, DAILY_VIEW) val viewToOpen = intent.getIntExtra(VIEW_TO_OPEN, DAILY_VIEW)
@@ -339,6 +375,10 @@ class MainActivity : SimpleActivity(), RefreshRecyclerViewListener {
currentFragments.last().goToToday() currentFragments.last().goToToday()
} }
fun showGoToDateDialog() {
currentFragments.last().showGoToDateDialog()
}
private fun resetActionBarTitle() { private fun resetActionBarTitle() {
updateActionBarTitle(getString(R.string.app_launcher_name)) updateActionBarTitle(getString(R.string.app_launcher_name))
updateActionBarSubtitle("") updateActionBarSubtitle("")
@@ -407,8 +447,10 @@ class MainActivity : SimpleActivity(), RefreshRecyclerViewListener {
private fun tryAddBirthdays() { private fun tryAddBirthdays() {
handlePermission(PERMISSION_READ_CONTACTS) { handlePermission(PERMISSION_READ_CONTACTS) {
if (it) { if (it) {
SetRemindersDialog(this) {
val reminders = it
Thread { Thread {
addContactEvents(true) { addContactEvents(true, reminders) {
if (it > 0) { if (it > 0) {
toast(R.string.birthdays_added) toast(R.string.birthdays_added)
updateViewPager() updateViewPager()
@@ -417,6 +459,7 @@ class MainActivity : SimpleActivity(), RefreshRecyclerViewListener {
} }
} }
}.start() }.start()
}
} else { } else {
toast(R.string.no_contacts_permission) toast(R.string.no_contacts_permission)
} }
@@ -426,8 +469,10 @@ class MainActivity : SimpleActivity(), RefreshRecyclerViewListener {
private fun tryAddAnniversaries() { private fun tryAddAnniversaries() {
handlePermission(PERMISSION_READ_CONTACTS) { handlePermission(PERMISSION_READ_CONTACTS) {
if (it) { if (it) {
SetRemindersDialog(this) {
val reminders = it
Thread { Thread {
addContactEvents(false) { addContactEvents(false, reminders) {
if (it > 0) { if (it > 0) {
toast(R.string.anniversaries_added) toast(R.string.anniversaries_added)
updateViewPager() updateViewPager()
@@ -436,6 +481,7 @@ class MainActivity : SimpleActivity(), RefreshRecyclerViewListener {
} }
} }
}.start() }.start()
}
} else { } else {
toast(R.string.no_contacts_permission) toast(R.string.no_contacts_permission)
} }
@@ -450,7 +496,7 @@ class MainActivity : SimpleActivity(), RefreshRecyclerViewListener {
}, Toast.LENGTH_LONG) }, Toast.LENGTH_LONG)
} }
private fun addContactEvents(birthdays: Boolean, callback: (Int) -> Unit) { private fun addContactEvents(birthdays: Boolean, reminders: ArrayList<Int>, callback: (Int) -> Unit) {
var eventsAdded = 0 var eventsAdded = 0
val uri = ContactsContract.Data.CONTENT_URI val uri = ContactsContract.Data.CONTENT_URI
val projection = arrayOf(ContactsContract.Contacts.DISPLAY_NAME, val projection = arrayOf(ContactsContract.Contacts.DISPLAY_NAME,
@@ -486,7 +532,8 @@ class MainActivity : SimpleActivity(), RefreshRecyclerViewListener {
val timestamp = date.time / 1000L val timestamp = date.time / 1000L
val source = if (birthdays) SOURCE_CONTACT_BIRTHDAY else SOURCE_CONTACT_ANNIVERSARY val source = if (birthdays) SOURCE_CONTACT_BIRTHDAY else SOURCE_CONTACT_ANNIVERSARY
val lastUpdated = cursor.getLongValue(ContactsContract.CommonDataKinds.Event.CONTACT_LAST_UPDATED_TIMESTAMP) val lastUpdated = cursor.getLongValue(ContactsContract.CommonDataKinds.Event.CONTACT_LAST_UPDATED_TIMESTAMP)
val event = Event(null, timestamp, timestamp, name, importId = contactId, flags = FLAG_ALL_DAY, repeatInterval = YEAR, val event = Event(null, timestamp, timestamp, name, reminder1Minutes = reminders[0], reminder2Minutes = reminders[1],
reminder3Minutes = reminders[2], importId = contactId, flags = FLAG_ALL_DAY, repeatInterval = YEAR, repeatRule = REPEAT_SAME_DAY,
eventType = eventTypeId, source = source, lastUpdated = lastUpdated) eventType = eventTypeId, source = source, lastUpdated = lastUpdated)
if (!importIDs.contains(contactId)) { if (!importIDs.contains(contactId)) {
@@ -861,6 +908,7 @@ class MainActivity : SimpleActivity(), RefreshRecyclerViewListener {
add(Release(117, R.string.release_117)) add(Release(117, R.string.release_117))
add(Release(119, R.string.release_119)) add(Release(119, R.string.release_119))
add(Release(129, R.string.release_129)) add(Release(129, R.string.release_129))
add(Release(143, R.string.release_143))
checkWhatsNew(this, BuildConfig.VERSION_CODE) checkWhatsNew(this, BuildConfig.VERSION_CODE)
} }
} }

View File

@@ -315,7 +315,6 @@ class SettingsActivity : SimpleActivity() {
} }
} }
private fun setupWeekNumbers() { private fun setupWeekNumbers() {
settings_week_numbers.isChecked = config.showWeekNumbers settings_week_numbers.isChecked = config.showWeekNumbers
settings_week_numbers_holder.setOnClickListener { settings_week_numbers_holder.setOnClickListener {
@@ -692,6 +691,8 @@ class SettingsActivity : SimpleActivity() {
private fun setupImportSettings() { private fun setupImportSettings() {
settings_import_holder.setOnClickListener { settings_import_holder.setOnClickListener {
handlePermission(PERMISSION_READ_STORAGE) {
if (it) {
FilePickerDialog(this) { FilePickerDialog(this) {
Thread { Thread {
try { try {
@@ -703,6 +704,8 @@ class SettingsActivity : SimpleActivity() {
} }
} }
} }
}
}
private fun parseFile(path: String) { private fun parseFile(path: String) {
val inputStream = File(path).inputStream() val inputStream = File(path).inputStream()

View File

@@ -1,8 +1,10 @@
package com.simplemobiletools.calendar.pro.activities package com.simplemobiletools.calendar.pro.activities
import android.content.Intent import android.content.Intent
import com.simplemobiletools.calendar.pro.extensions.getNewEventTimestampFromCode
import com.simplemobiletools.calendar.pro.helpers.* import com.simplemobiletools.calendar.pro.helpers.*
import com.simplemobiletools.commons.activities.BaseSplashActivity import com.simplemobiletools.commons.activities.BaseSplashActivity
import org.joda.time.DateTime
class SplashActivity : BaseSplashActivity() { class SplashActivity : BaseSplashActivity() {
override fun getAppPackageName() = packageName override fun getAppPackageName() = packageName
@@ -19,6 +21,13 @@ class SplashActivity : BaseSplashActivity() {
putExtra(EVENT_OCCURRENCE_TS, intent.getLongExtra(EVENT_OCCURRENCE_TS, 0L)) putExtra(EVENT_OCCURRENCE_TS, intent.getLongExtra(EVENT_OCCURRENCE_TS, 0L))
startActivity(this) startActivity(this)
} }
intent.action == SHORTCUT_NEW_EVENT -> {
val dayCode = Formatter.getDayCodeFromDateTime(DateTime())
Intent(this, EventActivity::class.java).apply {
putExtra(NEW_EVENT_START_TS, getNewEventTimestampFromCode(dayCode))
startActivity(this)
}
}
else -> startActivity(Intent(this, MainActivity::class.java)) else -> startActivity(Intent(this, MainActivity::class.java))
} }
finish() finish()

View File

@@ -68,12 +68,7 @@ class WidgetListConfigureActivity : SimpleActivity() {
updateColors() updateColors()
mBgColor = config.widgetBgColor mBgColor = config.widgetBgColor
if (mBgColor == 1) {
mBgColor = Color.BLACK
mBgAlpha = .2f
} else {
mBgAlpha = Color.alpha(mBgColor) / 255.toFloat() mBgAlpha = Color.alpha(mBgColor) / 255.toFloat()
}
mBgColorWithoutTransparency = Color.rgb(Color.red(mBgColor), Color.green(mBgColor), Color.blue(mBgColor)) mBgColorWithoutTransparency = Color.rgb(Color.red(mBgColor), Color.green(mBgColor), Color.blue(mBgColor))
config_bg_seekbar.setOnSeekBarChangeListener(bgSeekbarChangeListener) config_bg_seekbar.setOnSeekBarChangeListener(bgSeekbarChangeListener)

View File

@@ -77,12 +77,7 @@ class WidgetMonthlyConfigureActivity : SimpleActivity(), MonthlyCalendar {
updateColors() updateColors()
mBgColor = config.widgetBgColor mBgColor = config.widgetBgColor
if (mBgColor == 1) {
mBgColor = Color.BLACK
mBgAlpha = .2f
} else {
mBgAlpha = Color.alpha(mBgColor) / 255.toFloat() mBgAlpha = Color.alpha(mBgColor) / 255.toFloat()
}
mBgColorWithoutTransparency = Color.rgb(Color.red(mBgColor), Color.green(mBgColor), Color.blue(mBgColor)) mBgColorWithoutTransparency = Color.rgb(Color.red(mBgColor), Color.green(mBgColor), Color.blue(mBgColor))
config_bg_seekbar.setOnSeekBarChangeListener(bgSeekbarChangeListener) config_bg_seekbar.setOnSeekBarChangeListener(bgSeekbarChangeListener)

View File

@@ -0,0 +1,101 @@
package com.simplemobiletools.calendar.pro.adapters
import android.graphics.drawable.LayerDrawable
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ArrayAdapter
import android.widget.Filter
import com.bumptech.glide.Glide
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
import com.bumptech.glide.request.RequestOptions
import com.simplemobiletools.calendar.pro.R
import com.simplemobiletools.calendar.pro.activities.SimpleActivity
import com.simplemobiletools.calendar.pro.extensions.config
import com.simplemobiletools.calendar.pro.models.Attendee
import com.simplemobiletools.commons.extensions.applyColorFilter
import com.simplemobiletools.commons.extensions.normalizeString
import kotlinx.android.synthetic.main.item_autocomplete_email_name.view.*
class AutoCompleteTextViewAdapter(val activity: SimpleActivity, val contacts: ArrayList<Attendee>) : ArrayAdapter<Attendee>(activity, 0, contacts) {
var resultList = ArrayList<Attendee>()
private var placeholder = activity.resources.getDrawable(R.drawable.attendee_circular_background)
init {
(placeholder as LayerDrawable).findDrawableByLayerId(R.id.attendee_circular_background).applyColorFilter(activity.config.primaryColor)
}
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
val contact = resultList[position]
var listItem = convertView
if (listItem == null || listItem.tag != contact.name.isNotEmpty()) {
val layout = if (contact.name.isNotEmpty()) R.layout.item_autocomplete_email_name else R.layout.item_autocomplete_email
listItem = LayoutInflater.from(activity).inflate(layout, parent, false)
}
listItem!!.apply {
tag = contact.name.isNotEmpty()
item_autocomplete_name?.text = contact.name
item_autocomplete_email?.text = contact.email
if (contact.photoUri.isEmpty()) {
item_autocomplete_image.setImageDrawable(placeholder)
} else {
val options = RequestOptions()
.diskCacheStrategy(DiskCacheStrategy.RESOURCE)
.error(placeholder)
.centerCrop()
Glide.with(activity)
.load(contact.photoUri)
.transition(DrawableTransitionOptions.withCrossFade())
.apply(options)
.apply(RequestOptions.circleCropTransform())
.into(item_autocomplete_image)
}
}
return listItem
}
override fun getFilter() = object : Filter() {
override fun performFiltering(constraint: CharSequence?): FilterResults {
val filterResults = Filter.FilterResults()
if (constraint != null) {
resultList.clear()
val searchString = constraint.toString().normalizeString()
contacts.forEach {
if (it.email.contains(searchString, true) || it.name.contains(searchString, true)) {
resultList.add(it)
}
}
resultList.sortWith(compareBy<Attendee>
{ it.name.startsWith(searchString, true) }.thenBy
{ it.email.startsWith(searchString, true) }.thenBy
{ it.name.contains(searchString, true) }.thenBy
{ it.email.contains(searchString, true) })
resultList.reverse()
filterResults.values = resultList
filterResults.count = resultList.size
}
return filterResults
}
override fun publishResults(constraint: CharSequence?, results: FilterResults?) {
if (results?.count ?: -1 > 0) {
notifyDataSetChanged()
} else {
notifyDataSetInvalidated()
}
}
override fun convertResultToString(resultValue: Any?) = (resultValue as? Attendee)?.getPublicName()
}
override fun getItem(index: Int) = resultList[index]
override fun getCount() = resultList.size
}

View File

@@ -5,6 +5,7 @@ import androidx.room.Database
import androidx.room.Room import androidx.room.Room
import androidx.room.RoomDatabase import androidx.room.RoomDatabase
import androidx.room.TypeConverters import androidx.room.TypeConverters
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase import androidx.sqlite.db.SupportSQLiteDatabase
import com.simplemobiletools.calendar.pro.R import com.simplemobiletools.calendar.pro.R
import com.simplemobiletools.calendar.pro.extensions.config import com.simplemobiletools.calendar.pro.extensions.config
@@ -16,7 +17,7 @@ import com.simplemobiletools.calendar.pro.models.Event
import com.simplemobiletools.calendar.pro.models.EventType import com.simplemobiletools.calendar.pro.models.EventType
import java.util.concurrent.Executors import java.util.concurrent.Executors
@Database(entities = [Event::class, EventType::class], version = 1) @Database(entities = [Event::class, EventType::class], version = 2)
@TypeConverters(Converters::class) @TypeConverters(Converters::class)
abstract class EventsDatabase : RoomDatabase() { abstract class EventsDatabase : RoomDatabase() {
@@ -38,6 +39,7 @@ abstract class EventsDatabase : RoomDatabase() {
insertRegularEventType(context) insertRegularEventType(context)
} }
}) })
.addMigrations(MIGRATION_1_2)
.build() .build()
db!!.openHelper.setWriteAheadLoggingEnabled(true) db!!.openHelper.setWriteAheadLoggingEnabled(true)
} }
@@ -58,5 +60,16 @@ abstract class EventsDatabase : RoomDatabase() {
context.config.addDisplayEventType(REGULAR_EVENT_TYPE_ID.toString()) context.config.addDisplayEventType(REGULAR_EVENT_TYPE_ID.toString())
} }
} }
private val MIGRATION_1_2 = object : Migration(1, 2) {
override fun migrate(database: SupportSQLiteDatabase) {
database.apply {
execSQL("ALTER TABLE events ADD COLUMN reminder_1_type INTEGER NOT NULL DEFAULT 0")
execSQL("ALTER TABLE events ADD COLUMN reminder_2_type INTEGER NOT NULL DEFAULT 0")
execSQL("ALTER TABLE events ADD COLUMN reminder_3_type INTEGER NOT NULL DEFAULT 0")
execSQL("ALTER TABLE events ADD COLUMN attendees TEXT NOT NULL DEFAULT ''")
}
}
}
} }
} }

View File

@@ -0,0 +1,63 @@
package com.simplemobiletools.calendar.pro.dialogs
import android.app.Activity
import androidx.appcompat.app.AlertDialog
import com.simplemobiletools.calendar.pro.R
import com.simplemobiletools.calendar.pro.extensions.config
import com.simplemobiletools.commons.extensions.*
import kotlinx.android.synthetic.main.dialog_set_reminders.view.*
class SetRemindersDialog(val activity: Activity, val callback: (reminders: ArrayList<Int>) -> Unit) {
private var mReminder1Minutes = -1
private var mReminder2Minutes = -1
private var mReminder3Minutes = -1
init {
val view = activity.layoutInflater.inflate(R.layout.dialog_set_reminders, null).apply {
set_reminders_image.applyColorFilter(context.config.textColor)
set_reminders_1.text = activity.getFormattedMinutes(mReminder1Minutes)
set_reminders_2.text = activity.getFormattedMinutes(mReminder1Minutes)
set_reminders_3.text = activity.getFormattedMinutes(mReminder1Minutes)
set_reminders_1.setOnClickListener {
activity.showPickSecondsDialogHelper(mReminder1Minutes) {
mReminder1Minutes = if (it <= 0) it else it / 60
set_reminders_1.text = activity.getFormattedMinutes(mReminder1Minutes)
if (mReminder1Minutes != -1) {
set_reminders_2.beVisible()
}
}
}
set_reminders_2.setOnClickListener {
activity.showPickSecondsDialogHelper(mReminder2Minutes) {
mReminder2Minutes = if (it <= 0) it else it / 60
set_reminders_2.text = activity.getFormattedMinutes(mReminder2Minutes)
if (mReminder2Minutes != -1) {
set_reminders_3.beVisible()
}
}
}
set_reminders_3.setOnClickListener {
activity.showPickSecondsDialogHelper(mReminder3Minutes) {
mReminder3Minutes = if (it <= 0) it else it / 60
set_reminders_3.text = activity.getFormattedMinutes(mReminder3Minutes)
}
}
}
AlertDialog.Builder(activity)
.setPositiveButton(R.string.ok) { dialog, which -> dialogConfirmed() }
.setNegativeButton(R.string.cancel, null)
.create().apply {
activity.setupDialogStuff(view, this, R.string.event_reminders)
}
}
private fun dialogConfirmed() {
val reminders = arrayListOf(mReminder1Minutes, mReminder2Minutes, mReminder3Minutes)
reminders.sort()
callback(reminders)
}
}

View File

@@ -80,7 +80,8 @@ fun Context.scheduleAllEvents() {
} }
fun Context.scheduleNextEventReminder(event: Event, showToasts: Boolean) { fun Context.scheduleNextEventReminder(event: Event, showToasts: Boolean) {
if (event.getReminders().isEmpty()) { val validReminders = event.getReminders().filter { it.type == REMINDER_NOTIFICATION }
if (validReminders.isEmpty()) {
if (showToasts) { if (showToasts) {
toast(R.string.saving) toast(R.string.saving)
} }
@@ -88,7 +89,7 @@ fun Context.scheduleNextEventReminder(event: Event, showToasts: Boolean) {
} }
val now = getNowSeconds() val now = getNowSeconds()
val reminderSeconds = event.getReminders().reversed().map { it * 60 } val reminderSeconds = validReminders.reversed().map { it.minutes * 60 }
eventsHelper.getEvents(now, now + YEAR, event.id!!, false) { eventsHelper.getEvents(now, now + YEAR, event.id!!, false) {
if (it.isNotEmpty()) { if (it.isNotEmpty()) {
for (curEvent in it) { for (curEvent in it) {
@@ -159,7 +160,7 @@ fun Context.getRepetitionText(seconds: Int) = when (seconds) {
} }
fun Context.notifyRunningEvents() { fun Context.notifyRunningEvents() {
eventsHelper.getRunningEvents().filter { it.getReminders().isNotEmpty() }.forEach { eventsHelper.getRunningEvents().filter { it.getReminders().any { it.type == REMINDER_NOTIFICATION } }.forEach {
notifyEvent(it) notifyEvent(it)
} }
} }
@@ -408,6 +409,7 @@ fun Context.addDayEvents(day: DayMonthly, linearLayout: LinearLayout, res: Resou
text = it.title.replace(" ", "\u00A0") // allow word break by char text = it.title.replace(" ", "\u00A0") // allow word break by char
background = backgroundDrawable background = backgroundDrawable
layoutParams = eventLayoutParams layoutParams = eventLayoutParams
contentDescription = it.title
linearLayout.addView(this) linearLayout.addView(this)
} }
} }

View File

@@ -5,12 +5,11 @@ import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.DatePicker
import android.widget.RelativeLayout import android.widget.RelativeLayout
import androidx.appcompat.app.AlertDialog
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import com.simplemobiletools.calendar.pro.R import com.simplemobiletools.calendar.pro.R
import com.simplemobiletools.calendar.pro.activities.EventActivity import com.simplemobiletools.calendar.pro.activities.EventActivity
import com.simplemobiletools.calendar.pro.activities.MainActivity
import com.simplemobiletools.calendar.pro.activities.SimpleActivity import com.simplemobiletools.calendar.pro.activities.SimpleActivity
import com.simplemobiletools.calendar.pro.adapters.DayEventsAdapter import com.simplemobiletools.calendar.pro.adapters.DayEventsAdapter
import com.simplemobiletools.calendar.pro.extensions.config import com.simplemobiletools.calendar.pro.extensions.config
@@ -22,11 +21,8 @@ import com.simplemobiletools.calendar.pro.helpers.Formatter
import com.simplemobiletools.calendar.pro.interfaces.NavigationListener import com.simplemobiletools.calendar.pro.interfaces.NavigationListener
import com.simplemobiletools.calendar.pro.models.Event import com.simplemobiletools.calendar.pro.models.Event
import com.simplemobiletools.commons.extensions.applyColorFilter import com.simplemobiletools.commons.extensions.applyColorFilter
import com.simplemobiletools.commons.extensions.getDialogTheme
import com.simplemobiletools.commons.extensions.setupDialogStuff
import kotlinx.android.synthetic.main.fragment_day.view.* import kotlinx.android.synthetic.main.fragment_day.view.*
import kotlinx.android.synthetic.main.top_navigation.view.* import kotlinx.android.synthetic.main.top_navigation.view.*
import org.joda.time.DateTime
import java.util.* import java.util.*
class DayFragment : Fragment() { class DayFragment : Fragment() {
@@ -81,35 +77,14 @@ class DayFragment : Fragment() {
val day = Formatter.getDayTitle(context!!, mDayCode) val day = Formatter.getDayTitle(context!!, mDayCode)
mHolder.top_value.apply { mHolder.top_value.apply {
text = day text = day
setOnClickListener { pickDay() } contentDescription = text
setOnClickListener {
(activity as MainActivity).showGoToDateDialog()
}
setTextColor(context.config.textColor) setTextColor(context.config.textColor)
} }
} }
private fun pickDay() {
activity!!.setTheme(context!!.getDialogTheme())
val view = layoutInflater.inflate(R.layout.date_picker, null)
val datePicker = view.findViewById<DatePicker>(R.id.date_picker)
val dateTime = Formatter.getDateTimeFromCode(mDayCode)
datePicker.init(dateTime.year, dateTime.monthOfYear - 1, dateTime.dayOfMonth, null)
AlertDialog.Builder(context!!)
.setNegativeButton(R.string.cancel, null)
.setPositiveButton(R.string.ok) { dialog, which -> positivePressed(dateTime, datePicker) }
.create().apply {
activity?.setupDialogStuff(view, this)
}
}
private fun positivePressed(dateTime: DateTime, datePicker: DatePicker) {
val month = datePicker.month + 1
val year = datePicker.year
val day = datePicker.dayOfMonth
val newDateTime = dateTime.withDate(year, month, day)
mListener?.goToDateTime(newDateTime)
}
fun updateCalendar() { fun updateCalendar() {
val startTS = Formatter.getDayStartTS(mDayCode) val startTS = Formatter.getDayStartTS(mDayCode)
val endTS = Formatter.getDayEndTS(mDayCode) val endTS = Formatter.getDayEndTS(mDayCode)

View File

@@ -5,6 +5,8 @@ import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.DatePicker
import androidx.appcompat.app.AlertDialog
import androidx.viewpager.widget.ViewPager import androidx.viewpager.widget.ViewPager
import com.simplemobiletools.calendar.pro.R import com.simplemobiletools.calendar.pro.R
import com.simplemobiletools.calendar.pro.activities.MainActivity import com.simplemobiletools.calendar.pro.activities.MainActivity
@@ -13,6 +15,8 @@ import com.simplemobiletools.calendar.pro.extensions.config
import com.simplemobiletools.calendar.pro.helpers.DAY_CODE import com.simplemobiletools.calendar.pro.helpers.DAY_CODE
import com.simplemobiletools.calendar.pro.helpers.Formatter import com.simplemobiletools.calendar.pro.helpers.Formatter
import com.simplemobiletools.calendar.pro.interfaces.NavigationListener import com.simplemobiletools.calendar.pro.interfaces.NavigationListener
import com.simplemobiletools.commons.extensions.getDialogTheme
import com.simplemobiletools.commons.extensions.setupDialogStuff
import com.simplemobiletools.commons.extensions.updateActionBarTitle import com.simplemobiletools.commons.extensions.updateActionBarTitle
import com.simplemobiletools.commons.views.MyViewPager import com.simplemobiletools.commons.views.MyViewPager
import kotlinx.android.synthetic.main.fragment_days_holder.view.* import kotlinx.android.synthetic.main.fragment_days_holder.view.*
@@ -99,6 +103,30 @@ class DayFragmentsHolder : MyFragmentHolder(), NavigationListener {
setupFragment() setupFragment()
} }
override fun showGoToDateDialog() {
activity!!.setTheme(context!!.getDialogTheme())
val view = layoutInflater.inflate(R.layout.date_picker, null)
val datePicker = view.findViewById<DatePicker>(R.id.date_picker)
val dateTime = Formatter.getDateTimeFromCode(currentDayCode)
datePicker.init(dateTime.year, dateTime.monthOfYear - 1, dateTime.dayOfMonth, null)
AlertDialog.Builder(context!!)
.setNegativeButton(R.string.cancel, null)
.setPositiveButton(R.string.ok) { dialog, which -> dateSelected(dateTime, datePicker) }
.create().apply {
activity?.setupDialogStuff(view, this)
}
}
private fun dateSelected(dateTime: DateTime, datePicker: DatePicker) {
val month = datePicker.month + 1
val year = datePicker.year
val day = datePicker.dayOfMonth
val newDateTime = dateTime.withDate(year, month, day)
goToDateTime(newDateTime)
}
override fun refreshEvents() { override fun refreshEvents() {
(viewPager?.adapter as? MyDayPagerAdapter)?.updateCalendars(viewPager?.currentItem ?: 0) (viewPager?.adapter as? MyDayPagerAdapter)?.updateCalendars(viewPager?.currentItem ?: 0)
} }

View File

@@ -173,8 +173,9 @@ class EventListFragment : MyFragmentHolder(), RefreshRecyclerViewListener {
checkEvents() checkEvents()
} }
override fun goToToday() { override fun goToToday() {}
}
override fun showGoToDateDialog() {}
override fun refreshEvents() { override fun refreshEvents() {
checkEvents() checkEvents()

View File

@@ -6,9 +6,7 @@ import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.DatePicker
import android.widget.RelativeLayout import android.widget.RelativeLayout
import androidx.appcompat.app.AlertDialog
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import com.simplemobiletools.calendar.pro.R import com.simplemobiletools.calendar.pro.R
import com.simplemobiletools.calendar.pro.activities.MainActivity import com.simplemobiletools.calendar.pro.activities.MainActivity
@@ -21,9 +19,6 @@ import com.simplemobiletools.calendar.pro.interfaces.MonthlyCalendar
import com.simplemobiletools.calendar.pro.interfaces.NavigationListener import com.simplemobiletools.calendar.pro.interfaces.NavigationListener
import com.simplemobiletools.calendar.pro.models.DayMonthly import com.simplemobiletools.calendar.pro.models.DayMonthly
import com.simplemobiletools.commons.extensions.applyColorFilter import com.simplemobiletools.commons.extensions.applyColorFilter
import com.simplemobiletools.commons.extensions.beGone
import com.simplemobiletools.commons.extensions.getDialogTheme
import com.simplemobiletools.commons.extensions.setupDialogStuff
import kotlinx.android.synthetic.main.fragment_month.view.* import kotlinx.android.synthetic.main.fragment_month.view.*
import kotlinx.android.synthetic.main.top_navigation.view.* import kotlinx.android.synthetic.main.top_navigation.view.*
import org.joda.time.DateTime import org.joda.time.DateTime
@@ -100,6 +95,7 @@ class MonthFragment : Fragment(), MonthlyCalendar {
activity?.runOnUiThread { activity?.runOnUiThread {
mHolder.top_value.apply { mHolder.top_value.apply {
text = month text = month
contentDescription = text
setTextColor(mConfig.textColor) setTextColor(mConfig.textColor)
} }
updateDays(days) updateDays(days)
@@ -136,35 +132,11 @@ class MonthFragment : Fragment(), MonthlyCalendar {
mHolder.top_value.apply { mHolder.top_value.apply {
setTextColor(mConfig.textColor) setTextColor(mConfig.textColor)
setOnClickListener { setOnClickListener {
showMonthDialog() (activity as MainActivity).showGoToDateDialog()
} }
} }
} }
private fun showMonthDialog() {
activity!!.setTheme(context!!.getDialogTheme())
val view = layoutInflater.inflate(R.layout.date_picker, null)
val datePicker = view.findViewById<DatePicker>(R.id.date_picker)
datePicker.findViewById<View>(Resources.getSystem().getIdentifier("day", "id", "android")).beGone()
val dateTime = DateTime(mCalendar!!.mTargetDate.toString())
datePicker.init(dateTime.year, dateTime.monthOfYear - 1, 1, null)
AlertDialog.Builder(context!!)
.setNegativeButton(R.string.cancel, null)
.setPositiveButton(R.string.ok) { dialog, which -> positivePressed(dateTime, datePicker) }
.create().apply {
activity?.setupDialogStuff(view, this)
}
}
private fun positivePressed(dateTime: DateTime, datePicker: DatePicker) {
val month = datePicker.month + 1
val year = datePicker.year
val newDateTime = dateTime.withDate(year, month, 1)
listener?.goToDateTime(newDateTime)
}
private fun updateDays(days: ArrayList<DayMonthly>) { private fun updateDays(days: ArrayList<DayMonthly>) {
mHolder.month_view_wrapper.updateDays(days) { mHolder.month_view_wrapper.updateDays(days) {
(activity as MainActivity).openDayFromMonthly(Formatter.getDateTimeFromCode(it.code)) (activity as MainActivity).openDayFromMonthly(Formatter.getDateTimeFromCode(it.code))

View File

@@ -1,10 +1,13 @@
package com.simplemobiletools.calendar.pro.fragments package com.simplemobiletools.calendar.pro.fragments
import android.content.res.Resources
import android.graphics.drawable.ColorDrawable import android.graphics.drawable.ColorDrawable
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.DatePicker
import androidx.appcompat.app.AlertDialog
import androidx.viewpager.widget.ViewPager import androidx.viewpager.widget.ViewPager
import com.simplemobiletools.calendar.pro.R import com.simplemobiletools.calendar.pro.R
import com.simplemobiletools.calendar.pro.activities.MainActivity import com.simplemobiletools.calendar.pro.activities.MainActivity
@@ -14,6 +17,9 @@ import com.simplemobiletools.calendar.pro.extensions.getMonthCode
import com.simplemobiletools.calendar.pro.helpers.DAY_CODE import com.simplemobiletools.calendar.pro.helpers.DAY_CODE
import com.simplemobiletools.calendar.pro.helpers.Formatter import com.simplemobiletools.calendar.pro.helpers.Formatter
import com.simplemobiletools.calendar.pro.interfaces.NavigationListener import com.simplemobiletools.calendar.pro.interfaces.NavigationListener
import com.simplemobiletools.commons.extensions.beGone
import com.simplemobiletools.commons.extensions.getDialogTheme
import com.simplemobiletools.commons.extensions.setupDialogStuff
import com.simplemobiletools.commons.extensions.updateActionBarTitle import com.simplemobiletools.commons.extensions.updateActionBarTitle
import com.simplemobiletools.commons.views.MyViewPager import com.simplemobiletools.commons.views.MyViewPager
import kotlinx.android.synthetic.main.fragment_months_holder.view.* import kotlinx.android.synthetic.main.fragment_months_holder.view.*
@@ -99,6 +105,30 @@ class MonthFragmentsHolder : MyFragmentHolder(), NavigationListener {
setupFragment() setupFragment()
} }
override fun showGoToDateDialog() {
activity!!.setTheme(context!!.getDialogTheme())
val view = layoutInflater.inflate(R.layout.date_picker, null)
val datePicker = view.findViewById<DatePicker>(R.id.date_picker)
datePicker.findViewById<View>(Resources.getSystem().getIdentifier("day", "id", "android")).beGone()
val dateTime = DateTime(Formatter.getDateTimeFromCode(currentDayCode).toString())
datePicker.init(dateTime.year, dateTime.monthOfYear - 1, 1, null)
AlertDialog.Builder(context!!)
.setNegativeButton(R.string.cancel, null)
.setPositiveButton(R.string.ok) { dialog, which -> datePicked(dateTime, datePicker) }
.create().apply {
activity?.setupDialogStuff(view, this)
}
}
private fun datePicked(dateTime: DateTime, datePicker: DatePicker) {
val month = datePicker.month + 1
val year = datePicker.year
val newDateTime = dateTime.withDate(year, month, 1)
goToDateTime(newDateTime)
}
override fun refreshEvents() { override fun refreshEvents() {
(viewPager?.adapter as? MyMonthPagerAdapter)?.updateCalendars(viewPager?.currentItem ?: 0) (viewPager?.adapter as? MyMonthPagerAdapter)?.updateCalendars(viewPager?.currentItem ?: 0)
} }

View File

@@ -5,6 +5,8 @@ import androidx.fragment.app.Fragment
abstract class MyFragmentHolder : Fragment() { abstract class MyFragmentHolder : Fragment() {
abstract fun goToToday() abstract fun goToToday()
abstract fun showGoToDateDialog()
abstract fun refreshEvents() abstract fun refreshEvents()
abstract fun shouldGoToTodayBeVisible(): Boolean abstract fun shouldGoToTodayBeVisible(): Boolean

View File

@@ -322,6 +322,7 @@ class WeekFragment : Fragment(), WeeklyCalendar {
background = ColorDrawable(backgroundColor) background = ColorDrawable(backgroundColor)
setTextColor(textColor) setTextColor(textColor)
text = event.title text = event.title
contentDescription = text
layout.addView(this) layout.addView(this)
y = startMinutes * minuteHeight y = startMinutes * minuteHeight
(layoutParams as RelativeLayout.LayoutParams).apply { (layoutParams as RelativeLayout.LayoutParams).apply {
@@ -406,6 +407,7 @@ class WeekFragment : Fragment(), WeeklyCalendar {
setTextColor(textColor) setTextColor(textColor)
text = event.title text = event.title
contentDescription = text
val startDateTime = Formatter.getDateTimeFromTS(event.startTS) val startDateTime = Formatter.getDateTimeFromTS(event.startTS)
val endDateTime = Formatter.getDateTimeFromTS(event.endTS) val endDateTime = Formatter.getDateTimeFromTS(event.endTS)

View File

@@ -5,7 +5,9 @@ import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.DatePicker
import android.widget.TextView import android.widget.TextView
import androidx.appcompat.app.AlertDialog
import androidx.viewpager.widget.ViewPager import androidx.viewpager.widget.ViewPager
import com.simplemobiletools.calendar.pro.R import com.simplemobiletools.calendar.pro.R
import com.simplemobiletools.calendar.pro.activities.MainActivity import com.simplemobiletools.calendar.pro.activities.MainActivity
@@ -16,6 +18,8 @@ import com.simplemobiletools.calendar.pro.helpers.Formatter
import com.simplemobiletools.calendar.pro.helpers.WEEK_START_DATE_TIME import com.simplemobiletools.calendar.pro.helpers.WEEK_START_DATE_TIME
import com.simplemobiletools.calendar.pro.interfaces.WeekFragmentListener import com.simplemobiletools.calendar.pro.interfaces.WeekFragmentListener
import com.simplemobiletools.calendar.pro.views.MyScrollView import com.simplemobiletools.calendar.pro.views.MyScrollView
import com.simplemobiletools.commons.extensions.getDialogTheme
import com.simplemobiletools.commons.extensions.setupDialogStuff
import com.simplemobiletools.commons.extensions.updateActionBarSubtitle import com.simplemobiletools.commons.extensions.updateActionBarSubtitle
import com.simplemobiletools.commons.extensions.updateActionBarTitle import com.simplemobiletools.commons.extensions.updateActionBarTitle
import com.simplemobiletools.commons.helpers.WEEK_SECONDS import com.simplemobiletools.commons.helpers.WEEK_SECONDS
@@ -100,10 +104,11 @@ class WeekFragmentsHolder : MyFragmentHolder(), WeekFragmentListener {
private fun getWeekTimestamps(targetSeconds: Long): List<Long> { private fun getWeekTimestamps(targetSeconds: Long): List<Long> {
val weekTSs = ArrayList<Long>(PREFILLED_WEEKS) val weekTSs = ArrayList<Long>(PREFILLED_WEEKS)
var currWeekTS = targetSeconds - (PREFILLED_WEEKS / 2 * WEEK_SECONDS) val dateTime = Formatter.getDateTimeFromTS(targetSeconds)
var currentWeek = dateTime.minusWeeks(PREFILLED_WEEKS / 2)
for (i in 0 until PREFILLED_WEEKS) { for (i in 0 until PREFILLED_WEEKS) {
weekTSs.add(currWeekTS) weekTSs.add(currentWeek.seconds())
currWeekTS += WEEK_SECONDS currentWeek = currentWeek.plusWeeks(1)
} }
return weekTSs return weekTSs
} }
@@ -130,6 +135,42 @@ class WeekFragmentsHolder : MyFragmentHolder(), WeekFragmentListener {
setupFragment() setupFragment()
} }
override fun showGoToDateDialog() {
activity!!.setTheme(context!!.getDialogTheme())
val view = layoutInflater.inflate(R.layout.date_picker, null)
val datePicker = view.findViewById<DatePicker>(R.id.date_picker)
val dateTime = Formatter.getDateTimeFromTS(currentWeekTS)
datePicker.init(dateTime.year, dateTime.monthOfYear - 1, dateTime.dayOfMonth, null)
AlertDialog.Builder(context!!)
.setNegativeButton(R.string.cancel, null)
.setPositiveButton(R.string.ok) { dialog, which -> dateSelected(dateTime, datePicker) }
.create().apply {
activity?.setupDialogStuff(view, this)
}
}
private fun dateSelected(dateTime: DateTime, datePicker: DatePicker) {
val isSundayFirst = context!!.config.isSundayFirst
val month = datePicker.month + 1
val year = datePicker.year
val day = datePicker.dayOfMonth
var newDateTime = dateTime.withDate(year, month, day)
if (isSundayFirst) {
newDateTime = newDateTime.plusDays(1)
}
var selectedWeek = newDateTime.withDayOfWeek(1).withTimeAtStartOfDay().minusDays(if (isSundayFirst) 1 else 0)
if (newDateTime.minusDays(7).seconds() > selectedWeek.seconds()) {
selectedWeek = selectedWeek.plusDays(7)
}
currentWeekTS = selectedWeek.seconds()
setupFragment()
}
override fun refreshEvents() { override fun refreshEvents() {
(viewPager?.adapter as? MyWeekPagerAdapter)?.updateCalendars(viewPager!!.currentItem) (viewPager?.adapter as? MyWeekPagerAdapter)?.updateCalendars(viewPager!!.currentItem)
} }

View File

@@ -1,16 +1,22 @@
package com.simplemobiletools.calendar.pro.fragments package com.simplemobiletools.calendar.pro.fragments
import android.content.res.Resources
import android.graphics.drawable.ColorDrawable import android.graphics.drawable.ColorDrawable
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.DatePicker
import androidx.appcompat.app.AlertDialog
import androidx.viewpager.widget.ViewPager import androidx.viewpager.widget.ViewPager
import com.simplemobiletools.calendar.pro.R import com.simplemobiletools.calendar.pro.R
import com.simplemobiletools.calendar.pro.activities.MainActivity import com.simplemobiletools.calendar.pro.activities.MainActivity
import com.simplemobiletools.calendar.pro.adapters.MyYearPagerAdapter import com.simplemobiletools.calendar.pro.adapters.MyYearPagerAdapter
import com.simplemobiletools.calendar.pro.extensions.config import com.simplemobiletools.calendar.pro.extensions.config
import com.simplemobiletools.calendar.pro.helpers.Formatter import com.simplemobiletools.calendar.pro.helpers.Formatter
import com.simplemobiletools.commons.extensions.beGone
import com.simplemobiletools.commons.extensions.getDialogTheme
import com.simplemobiletools.commons.extensions.setupDialogStuff
import com.simplemobiletools.commons.extensions.updateActionBarTitle import com.simplemobiletools.commons.extensions.updateActionBarTitle
import com.simplemobiletools.commons.views.MyViewPager import com.simplemobiletools.commons.views.MyViewPager
import kotlinx.android.synthetic.main.fragment_years_holder.view.* import kotlinx.android.synthetic.main.fragment_years_holder.view.*
@@ -83,6 +89,32 @@ class YearFragmentsHolder : MyFragmentHolder() {
setupFragment() setupFragment()
} }
override fun showGoToDateDialog() {
activity!!.setTheme(context!!.getDialogTheme())
val view = layoutInflater.inflate(R.layout.date_picker, null)
val datePicker = view.findViewById<DatePicker>(R.id.date_picker)
datePicker.findViewById<View>(Resources.getSystem().getIdentifier("day", "id", "android")).beGone()
datePicker.findViewById<View>(Resources.getSystem().getIdentifier("month", "id", "android")).beGone()
val dateTime = DateTime(Formatter.getDateTimeFromCode("${currentYear}0523").toString())
datePicker.init(dateTime.year, dateTime.monthOfYear - 1, 1, null)
AlertDialog.Builder(context!!)
.setNegativeButton(R.string.cancel, null)
.setPositiveButton(R.string.ok) { dialog, which -> datePicked(datePicker) }
.create().apply {
activity?.setupDialogStuff(view, this)
}
}
private fun datePicked(datePicker: DatePicker) {
val pickedYear = datePicker.year
if (currentYear != pickedYear) {
currentYear = datePicker.year
setupFragment()
}
}
override fun refreshEvents() { override fun refreshEvents() {
(viewPager?.adapter as? MyYearPagerAdapter)?.updateCalendars(viewPager?.currentItem ?: 0) (viewPager?.adapter as? MyYearPagerAdapter)?.updateCalendars(viewPager?.currentItem ?: 0)
} }

View File

@@ -8,11 +8,11 @@ import android.database.Cursor
import android.provider.CalendarContract import android.provider.CalendarContract
import android.provider.CalendarContract.Reminders import android.provider.CalendarContract.Reminders
import android.util.SparseIntArray import android.util.SparseIntArray
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import com.simplemobiletools.calendar.pro.R import com.simplemobiletools.calendar.pro.R
import com.simplemobiletools.calendar.pro.extensions.* import com.simplemobiletools.calendar.pro.extensions.*
import com.simplemobiletools.calendar.pro.models.CalDAVCalendar import com.simplemobiletools.calendar.pro.models.*
import com.simplemobiletools.calendar.pro.models.Event
import com.simplemobiletools.calendar.pro.models.EventType
import com.simplemobiletools.calendar.pro.objects.States.isUpdatingCalDAV import com.simplemobiletools.calendar.pro.objects.States.isUpdatingCalDAV
import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.PERMISSION_READ_CALENDAR import com.simplemobiletools.commons.helpers.PERMISSION_READ_CALENDAR
@@ -52,7 +52,7 @@ class CalDAVHelper(val context: Context) {
} }
@SuppressLint("MissingPermission") @SuppressLint("MissingPermission")
fun getCalDAVCalendars(ids: String, showToasts: Boolean): List<CalDAVCalendar> { fun getCalDAVCalendars(ids: String, showToasts: Boolean): ArrayList<CalDAVCalendar> {
val calendars = ArrayList<CalDAVCalendar>() val calendars = ArrayList<CalDAVCalendar>()
if (!context.hasPermission(PERMISSION_WRITE_CALENDAR) || !context.hasPermission(PERMISSION_READ_CALENDAR)) { if (!context.hasPermission(PERMISSION_WRITE_CALENDAR) || !context.hasPermission(PERMISSION_READ_CALENDAR)) {
return calendars return calendars
@@ -72,7 +72,7 @@ class CalDAVHelper(val context: Context) {
var cursor: Cursor? = null var cursor: Cursor? = null
try { try {
cursor = context.contentResolver.query(uri, projection, selection, null, null) cursor = context.contentResolver.query(uri, projection, selection, null, null)
if (cursor != null && cursor.moveToFirst()) { if (cursor?.moveToFirst() == true) {
do { do {
val id = cursor.getIntValue(CalendarContract.Calendars._ID) val id = cursor.getIntValue(CalendarContract.Calendars._ID)
val displayName = cursor.getStringValue(CalendarContract.Calendars.CALENDAR_DISPLAY_NAME) val displayName = cursor.getStringValue(CalendarContract.Calendars.CALENDAR_DISPLAY_NAME)
@@ -144,7 +144,7 @@ class CalDAVHelper(val context: Context) {
var cursor: Cursor? = null var cursor: Cursor? = null
try { try {
cursor = context.contentResolver.query(uri, projection, selection, selectionArgs, null) cursor = context.contentResolver.query(uri, projection, selection, selectionArgs, null)
if (cursor != null && cursor.moveToFirst()) { if (cursor?.moveToFirst() == true) {
do { do {
val colorKey = cursor.getIntValue(CalendarContract.Colors.COLOR_KEY) val colorKey = cursor.getIntValue(CalendarContract.Colors.COLOR_KEY)
val color = cursor.getIntValue(CalendarContract.Colors.COLOR) val color = cursor.getIntValue(CalendarContract.Colors.COLOR)
@@ -192,39 +192,37 @@ class CalDAVHelper(val context: Context) {
var cursor: Cursor? = null var cursor: Cursor? = null
try { try {
cursor = context.contentResolver.query(uri, projection, selection, null, null) cursor = context.contentResolver.query(uri, projection, selection, null, null)
if (cursor != null && cursor.moveToFirst()) { if (cursor?.moveToFirst() == true) {
do { do {
val id = cursor.getLongValue(CalendarContract.Events._ID) val id = cursor.getLongValue(CalendarContract.Events._ID)
val title = cursor.getStringValue(CalendarContract.Events.TITLE) ?: "" val title = cursor.getStringValue(CalendarContract.Events.TITLE) ?: ""
val description = cursor.getStringValue(CalendarContract.Events.DESCRIPTION) ?: "" val description = cursor.getStringValue(CalendarContract.Events.DESCRIPTION) ?: ""
var startTS = cursor.getLongValue(CalendarContract.Events.DTSTART) val startTS = cursor.getLongValue(CalendarContract.Events.DTSTART) / 1000L
var endTS = cursor.getLongValue(CalendarContract.Events.DTEND) var endTS = cursor.getLongValue(CalendarContract.Events.DTEND) / 1000L
val allDay = cursor.getIntValue(CalendarContract.Events.ALL_DAY) val allDay = cursor.getIntValue(CalendarContract.Events.ALL_DAY)
val rrule = cursor.getStringValue(CalendarContract.Events.RRULE) ?: "" val rrule = cursor.getStringValue(CalendarContract.Events.RRULE) ?: ""
val location = cursor.getStringValue(CalendarContract.Events.EVENT_LOCATION) ?: "" val location = cursor.getStringValue(CalendarContract.Events.EVENT_LOCATION) ?: ""
val originalId = cursor.getStringValue(CalendarContract.Events.ORIGINAL_ID) val originalId = cursor.getStringValue(CalendarContract.Events.ORIGINAL_ID)
val originalInstanceTime = cursor.getLongValue(CalendarContract.Events.ORIGINAL_INSTANCE_TIME) val originalInstanceTime = cursor.getLongValue(CalendarContract.Events.ORIGINAL_INSTANCE_TIME)
val reminders = getCalDAVEventReminders(id) val reminders = getCalDAVEventReminders(id)
val attendees = Gson().toJson(getCalDAVEventAttendees(id))
if (startTS.toString().length == 12 || startTS.toString().length == 13) {
startTS /= 1000L
}
if (endTS.toString().length == 12 || endTS.toString().length == 13) {
endTS /= 1000L
}
if (endTS == 0L) { if (endTS == 0L) {
val duration = cursor.getStringValue(CalendarContract.Events.DURATION) ?: "" val duration = cursor.getStringValue(CalendarContract.Events.DURATION) ?: ""
endTS = startTS + Parser().parseDurationSeconds(duration) endTS = startTS + Parser().parseDurationSeconds(duration)
} }
val reminder1 = reminders.getOrNull(0)
val reminder2 = reminders.getOrNull(1)
val reminder3 = reminders.getOrNull(2)
val importId = getCalDAVEventImportId(calendarId, id) val importId = getCalDAVEventImportId(calendarId, id)
val source = "$CALDAV-$calendarId" val source = "$CALDAV-$calendarId"
val repeatRule = Parser().parseRepeatInterval(rrule, startTS) val repeatRule = Parser().parseRepeatInterval(rrule, startTS)
val event = Event(null, startTS, endTS, title, location, description, reminders.getOrElse(0) { -1 }, val event = Event(null, startTS, endTS, title, location, description, reminder1?.minutes ?: REMINDER_OFF,
reminders.getOrElse(1) { -1 }, reminders.getOrElse(2) { -1 }, repeatRule.repeatInterval, repeatRule.repeatRule, reminder2?.minutes ?: REMINDER_OFF, reminder3?.minutes ?: REMINDER_OFF, reminder1?.type
repeatRule.repeatLimit, ArrayList(), importId, allDay, eventTypeId, source = source) ?: REMINDER_NOTIFICATION, reminder2?.type ?: REMINDER_NOTIFICATION, reminder3?.type
?: REMINDER_NOTIFICATION, repeatRule.repeatInterval, repeatRule.repeatRule,
repeatRule.repeatLimit, ArrayList(), attendees, importId, allDay, eventTypeId, source = source)
if (event.getIsAllDay()) { if (event.getIsAllDay()) {
event.startTS = Formatter.getShiftedImportTimestamp(event.startTS) event.startTS = Formatter.getShiftedImportTimestamp(event.startTS)
@@ -326,6 +324,7 @@ class CalDAVHelper(val context: Context) {
event.importId = getCalDAVEventImportId(calendarId, eventRemoteID) event.importId = getCalDAVEventImportId(calendarId, eventRemoteID)
setupCalDAVEventReminders(event) setupCalDAVEventReminders(event)
setupCalDAVEventAttendees(event)
setupCalDAVEventImportId(event) setupCalDAVEventImportId(event)
refreshCalDAVCalendar(event) refreshCalDAVCalendar(event)
} }
@@ -340,18 +339,18 @@ class CalDAVHelper(val context: Context) {
context.contentResolver.update(newUri, values, null, null) context.contentResolver.update(newUri, values, null, null)
setupCalDAVEventReminders(event) setupCalDAVEventReminders(event)
setupCalDAVEventAttendees(event)
setupCalDAVEventImportId(event) setupCalDAVEventImportId(event)
refreshCalDAVCalendar(event) refreshCalDAVCalendar(event)
} }
@SuppressLint("MissingPermission")
private fun setupCalDAVEventReminders(event: Event) { private fun setupCalDAVEventReminders(event: Event) {
clearEventReminders(event) clearEventReminders(event)
event.getReminders().forEach { event.getReminders().forEach {
val contentValues = ContentValues().apply { val contentValues = ContentValues().apply {
put(Reminders.MINUTES, it) put(Reminders.MINUTES, it.minutes)
put(Reminders.METHOD, if (it.type == REMINDER_EMAIL) Reminders.METHOD_EMAIL else Reminders.METHOD_ALERT)
put(Reminders.EVENT_ID, event.getCalDAVEventId()) put(Reminders.EVENT_ID, event.getCalDAVEventId())
put(Reminders.METHOD, Reminders.METHOD_ALERT)
} }
try { try {
@@ -362,6 +361,25 @@ class CalDAVHelper(val context: Context) {
} }
} }
private fun setupCalDAVEventAttendees(event: Event) {
clearEventAttendees(event)
val attendees = Gson().fromJson<ArrayList<Attendee>>(event.attendees, object : TypeToken<List<Attendee>>() {}.type) ?: ArrayList()
attendees.forEach {
val contentValues = ContentValues().apply {
put(CalendarContract.Attendees.ATTENDEE_NAME, it.name)
put(CalendarContract.Attendees.ATTENDEE_EMAIL, it.email)
put(CalendarContract.Attendees.ATTENDEE_STATUS, CalendarContract.Attendees.ATTENDEE_STATUS_ACCEPTED)
put(CalendarContract.Attendees.EVENT_ID, event.getCalDAVEventId())
}
try {
context.contentResolver.insert(CalendarContract.Attendees.CONTENT_URI, contentValues)
} catch (e: Exception) {
context.toast(R.string.unknown_error_occurred)
}
}
}
private fun setupCalDAVEventImportId(event: Event) { private fun setupCalDAVEventImportId(event: Event) {
context.eventsDB.updateEventImportIdAndSource(event.importId, "$CALDAV-${event.getCalDAVCalendarId()}", event.id!!) context.eventsDB.updateEventImportIdAndSource(event.importId, "$CALDAV-${event.getCalDAVCalendarId()}", event.id!!)
} }
@@ -397,13 +415,18 @@ class CalDAVHelper(val context: Context) {
} }
} }
@SuppressLint("MissingPermission")
private fun clearEventReminders(event: Event) { private fun clearEventReminders(event: Event) {
val selection = "${Reminders.EVENT_ID} = ?" val selection = "${Reminders.EVENT_ID} = ?"
val selectionArgs = arrayOf(event.getCalDAVEventId().toString()) val selectionArgs = arrayOf(event.getCalDAVEventId().toString())
context.contentResolver.delete(Reminders.CONTENT_URI, selection, selectionArgs) context.contentResolver.delete(Reminders.CONTENT_URI, selection, selectionArgs)
} }
private fun clearEventAttendees(event: Event) {
val selection = "${CalendarContract.Attendees.EVENT_ID} = ?"
val selectionArgs = arrayOf(event.getCalDAVEventId().toString())
context.contentResolver.delete(CalendarContract.Attendees.CONTENT_URI, selection, selectionArgs)
}
private fun getDurationCode(event: Event): String { private fun getDurationCode(event: Event): String {
return if (event.getIsAllDay()) { return if (event.getIsAllDay()) {
val dur = Math.max(1, (event.endTS - event.startTS) / DAY) val dur = Math.max(1, (event.endTS - event.startTS) / DAY)
@@ -428,7 +451,6 @@ class CalDAVHelper(val context: Context) {
refreshCalDAVCalendar(event) refreshCalDAVCalendar(event)
} }
@SuppressLint("MissingPermission")
fun insertEventRepeatException(event: Event, occurrenceTS: Long): Long { fun insertEventRepeatException(event: Event, occurrenceTS: Long): Long {
val uri = CalendarContract.Events.CONTENT_URI val uri = CalendarContract.Events.CONTENT_URI
val values = fillEventRepeatExceptionValues(event, occurrenceTS) val values = fillEventRepeatExceptionValues(event, occurrenceTS)
@@ -449,9 +471,8 @@ class CalDAVHelper(val context: Context) {
} }
} }
@SuppressLint("MissingPermission") private fun getCalDAVEventReminders(eventId: Long): List<Reminder> {
private fun getCalDAVEventReminders(eventId: Long): List<Int> { val reminders = ArrayList<Reminder>()
val reminders = ArrayList<Int>()
val uri = CalendarContract.Reminders.CONTENT_URI val uri = CalendarContract.Reminders.CONTENT_URI
val projection = arrayOf( val projection = arrayOf(
CalendarContract.Reminders.MINUTES, CalendarContract.Reminders.MINUTES,
@@ -460,19 +481,47 @@ class CalDAVHelper(val context: Context) {
var cursor: Cursor? = null var cursor: Cursor? = null
try { try {
cursor = context.contentResolver.query(uri, projection, selection, null, null) cursor = context.contentResolver.query(uri, projection, selection, null, null)
if (cursor != null && cursor.moveToFirst()) { if (cursor?.moveToFirst() == true) {
do { do {
val minutes = cursor.getIntValue(CalendarContract.Reminders.MINUTES) val minutes = cursor.getIntValue(CalendarContract.Reminders.MINUTES)
val method = cursor.getIntValue(CalendarContract.Reminders.METHOD) val method = cursor.getIntValue(CalendarContract.Reminders.METHOD)
if (method == CalendarContract.Reminders.METHOD_ALERT) { if (method == CalendarContract.Reminders.METHOD_ALERT || method == CalendarContract.Reminders.METHOD_EMAIL) {
reminders.add(minutes) val type = if (method == CalendarContract.Reminders.METHOD_EMAIL) REMINDER_EMAIL else REMINDER_NOTIFICATION
val reminder = Reminder(minutes, type)
reminders.add(reminder)
} }
} while (cursor.moveToNext()) } while (cursor.moveToNext())
} }
} finally { } finally {
cursor?.close() cursor?.close()
} }
return reminders return reminders.sortedBy { it.minutes }
}
private fun getCalDAVEventAttendees(eventId: Long): List<Attendee> {
val attendees = ArrayList<Attendee>()
val uri = CalendarContract.Attendees.CONTENT_URI
val projection = arrayOf(
CalendarContract.Attendees.ATTENDEE_NAME,
CalendarContract.Attendees.ATTENDEE_EMAIL,
CalendarContract.Attendees.ATTENDEE_STATUS)
val selection = "${CalendarContract.Attendees.EVENT_ID} = $eventId"
var cursor: Cursor? = null
try {
cursor = context.contentResolver.query(uri, projection, selection, null, null)
if (cursor?.moveToFirst() == true) {
do {
val name = cursor.getStringValue(CalendarContract.Attendees.ATTENDEE_NAME)
val email = cursor.getStringValue(CalendarContract.Attendees.ATTENDEE_EMAIL)
val status = cursor.getIntValue(CalendarContract.Attendees.ATTENDEE_STATUS)
val attendee = Attendee(0, name, email, status, "")
attendees.add(attendee)
} while (cursor.moveToNext())
}
} finally {
cursor?.close()
}
return attendees
} }
private fun getCalDAVEventImportId(calendarId: Int, eventId: Long) = "$CALDAV-$calendarId-$eventId" private fun getCalDAVEventImportId(calendarId: Int, eventId: Long) = "$CALDAV-$calendarId-$eventId"

View File

@@ -15,6 +15,7 @@ const val NEW_EVENT_SET_HOUR_DURATION = "new_event_set_hour_duration"
const val WEEK_START_DATE_TIME = "week_start_date_time" const val WEEK_START_DATE_TIME = "week_start_date_time"
const val CALDAV = "Caldav" const val CALDAV = "Caldav"
const val VIEW_TO_OPEN = "view_to_open" const val VIEW_TO_OPEN = "view_to_open"
const val SHORTCUT_NEW_EVENT = "shortcut_new_event"
const val REGULAR_EVENT_TYPE_ID = 1L const val REGULAR_EVENT_TYPE_ID = 1L
const val CHOPPED_LIST_DEFAULT_SIZE = 100 const val CHOPPED_LIST_DEFAULT_SIZE = 100
@@ -99,6 +100,8 @@ const val SUMMARY = "SUMMARY"
const val DESCRIPTION = "DESCRIPTION:" const val DESCRIPTION = "DESCRIPTION:"
const val UID = "UID:" const val UID = "UID:"
const val ACTION = "ACTION:" const val ACTION = "ACTION:"
const val ATTENDEE = "ATTENDEE:"
const val MAILTO = "mailto:"
const val TRIGGER = "TRIGGER:" const val TRIGGER = "TRIGGER:"
const val RRULE = "RRULE:" const val RRULE = "RRULE:"
const val CATEGORIES = "CATEGORIES:" const val CATEGORIES = "CATEGORIES:"
@@ -115,6 +118,7 @@ const val SEQUENCE = "SEQUENCE"
const val CATEGORY_COLOR = "CATEGORY_COLOR:" const val CATEGORY_COLOR = "CATEGORY_COLOR:"
const val DISPLAY = "DISPLAY" const val DISPLAY = "DISPLAY"
const val EMAIL = "EMAIL"
const val FREQ = "FREQ" const val FREQ = "FREQ"
const val UNTIL = "UNTIL" const val UNTIL = "UNTIL"
const val COUNT = "COUNT" const val COUNT = "COUNT"
@@ -150,4 +154,7 @@ const val DELETE_SELECTED_OCCURRENCE = 0
const val DELETE_FUTURE_OCCURRENCES = 1 const val DELETE_FUTURE_OCCURRENCES = 1
const val DELETE_ALL_OCCURRENCES = 2 const val DELETE_ALL_OCCURRENCES = 2
const val REMINDER_NOTIFICATION = 0
const val REMINDER_EMAIL = 1
fun getNowSeconds() = System.currentTimeMillis() / 1000L fun getNowSeconds() = System.currentTimeMillis() / 1000L

View File

@@ -253,9 +253,10 @@ class EventsHelper(val context: Context) {
eventTypeColors.put(it.id!!, it.color) eventTypeColors.put(it.id!!, it.color)
} }
val primaryColor = context.resources.getColor(R.color.color_primary)
events.forEach { events.forEach {
it.updateIsPastEvent() it.updateIsPastEvent()
it.color = eventTypeColors.get(it.eventType) ?: context.resources.getColor(R.color.color_primary) it.color = eventTypeColors.get(it.eventType) ?: primaryColor
} }
callback(events) callback(events)

View File

@@ -1,8 +1,10 @@
package com.simplemobiletools.calendar.pro.helpers package com.simplemobiletools.calendar.pro.helpers
import com.simplemobiletools.calendar.pro.R import com.simplemobiletools.calendar.pro.R
import com.simplemobiletools.calendar.pro.extensions.calDAVHelper
import com.simplemobiletools.calendar.pro.extensions.eventTypesDB import com.simplemobiletools.calendar.pro.extensions.eventTypesDB
import com.simplemobiletools.calendar.pro.helpers.IcsExporter.ExportResult.* import com.simplemobiletools.calendar.pro.helpers.IcsExporter.ExportResult.*
import com.simplemobiletools.calendar.pro.models.CalDAVCalendar
import com.simplemobiletools.calendar.pro.models.Event import com.simplemobiletools.calendar.pro.models.Event
import com.simplemobiletools.commons.activities.BaseSimpleActivity import com.simplemobiletools.commons.activities.BaseSimpleActivity
import com.simplemobiletools.commons.extensions.getFileOutputStream import com.simplemobiletools.commons.extensions.getFileOutputStream
@@ -19,6 +21,7 @@ class IcsExporter {
private var eventsExported = 0 private var eventsExported = 0
private var eventsFailed = 0 private var eventsFailed = 0
private var calendars = ArrayList<CalDAVCalendar>()
fun exportEvents(activity: BaseSimpleActivity, file: File, events: ArrayList<Event>, showExportingToast: Boolean, callback: (result: ExportResult) -> Unit) { fun exportEvents(activity: BaseSimpleActivity, file: File, events: ArrayList<Event>, showExportingToast: Boolean, callback: (result: ExportResult) -> Unit) {
val fileDirItem = FileDirItem(file.absolutePath, file.name) val fileDirItem = FileDirItem(file.absolutePath, file.name)
@@ -29,6 +32,7 @@ class IcsExporter {
} }
Thread { Thread {
calendars = activity.calDAVHelper.getCalDAVCalendars("", false)
if (showExportingToast) { if (showExportingToast) {
activity.toast(R.string.exporting) activity.toast(R.string.exporting)
} }
@@ -77,17 +81,20 @@ class IcsExporter {
} }
private fun fillReminders(event: Event, out: BufferedWriter) { private fun fillReminders(event: Event, out: BufferedWriter) {
checkReminder(event.reminder1Minutes, out) event.getReminders().forEach {
checkReminder(event.reminder2Minutes, out) val reminder = it
checkReminder(event.reminder3Minutes, out)
}
private fun checkReminder(minutes: Int, out: BufferedWriter) {
if (minutes != -1) {
out.apply { out.apply {
writeLn(BEGIN_ALARM) writeLn(BEGIN_ALARM)
if (reminder.type == REMINDER_NOTIFICATION) {
writeLn("$ACTION$DISPLAY") writeLn("$ACTION$DISPLAY")
writeLn("$TRIGGER-${Parser().getDurationCode(minutes.toLong())}") } else {
writeLn("$ACTION$EMAIL")
val attendee = calendars.firstOrNull { it.id == event.getCalDAVCalendarId()}?.accountName
if (attendee != null) {
writeLn("$ATTENDEE$MAILTO$attendee")
}
}
writeLn("$TRIGGER-${Parser().getDurationCode(reminder.minutes.toLong())}")
writeLn(END_ALARM) writeLn(END_ALARM)
} }
} }

View File

@@ -8,6 +8,7 @@ import com.simplemobiletools.calendar.pro.extensions.eventsHelper
import com.simplemobiletools.calendar.pro.helpers.IcsImporter.ImportResult.* import com.simplemobiletools.calendar.pro.helpers.IcsImporter.ImportResult.*
import com.simplemobiletools.calendar.pro.models.Event import com.simplemobiletools.calendar.pro.models.Event
import com.simplemobiletools.calendar.pro.models.EventType import com.simplemobiletools.calendar.pro.models.EventType
import com.simplemobiletools.calendar.pro.models.Reminder
import com.simplemobiletools.commons.extensions.areDigitsOnly import com.simplemobiletools.commons.extensions.areDigitsOnly
import com.simplemobiletools.commons.extensions.showErrorToast import com.simplemobiletools.commons.extensions.showErrorToast
import java.io.File import java.io.File
@@ -26,6 +27,7 @@ class IcsImporter(val activity: SimpleActivity) {
private var curRecurrenceDayCode = "" private var curRecurrenceDayCode = ""
private var curFlags = 0 private var curFlags = 0
private var curReminderMinutes = ArrayList<Int>() private var curReminderMinutes = ArrayList<Int>()
private var curReminderActions = ArrayList<Int>()
private var curRepeatExceptions = ArrayList<String>() private var curRepeatExceptions = ArrayList<String>()
private var curRepeatInterval = 0 private var curRepeatInterval = 0
private var curRepeatLimit = 0L private var curRepeatLimit = 0L
@@ -37,7 +39,8 @@ class IcsImporter(val activity: SimpleActivity) {
private var isProperReminderAction = false private var isProperReminderAction = false
private var isDescription = false private var isDescription = false
private var isSequence = false private var isSequence = false
private var curReminderTriggerMinutes = -1 private var curReminderTriggerMinutes = REMINDER_OFF
private var curReminderTriggerAction = REMINDER_NOTIFICATION
private val eventsHelper = activity.eventsHelper private val eventsHelper = activity.eventsHelper
private var eventsImported = 0 private var eventsImported = 0
@@ -101,7 +104,11 @@ class IcsImporter(val activity: SimpleActivity) {
curRepeatLimit = repeatRule.repeatLimit curRepeatLimit = repeatRule.repeatLimit
} else if (line.startsWith(ACTION)) { } else if (line.startsWith(ACTION)) {
isNotificationDescription = true isNotificationDescription = true
isProperReminderAction = line.substring(ACTION.length) == DISPLAY val action = line.substring(ACTION.length)
isProperReminderAction = action == DISPLAY || action == EMAIL
if (isProperReminderAction) {
curReminderTriggerAction = if (action == DISPLAY) REMINDER_NOTIFICATION else REMINDER_EMAIL
}
} else if (line.startsWith(TRIGGER)) { } else if (line.startsWith(TRIGGER)) {
curReminderTriggerMinutes = Parser().parseDurationSeconds(line.substring(TRIGGER.length)) / 60 curReminderTriggerMinutes = Parser().parseDurationSeconds(line.substring(TRIGGER.length)) / 60
} else if (line.startsWith(CATEGORY_COLOR)) { } else if (line.startsWith(CATEGORY_COLOR)) {
@@ -129,8 +136,9 @@ class IcsImporter(val activity: SimpleActivity) {
} else if (line.startsWith(SEQUENCE)) { } else if (line.startsWith(SEQUENCE)) {
isSequence = true isSequence = true
} else if (line == END_ALARM) { } else if (line == END_ALARM) {
if (isProperReminderAction && curReminderTriggerMinutes != -1) { if (isProperReminderAction && curReminderTriggerMinutes != REMINDER_OFF) {
curReminderMinutes.add(curReminderTriggerMinutes) curReminderMinutes.add(curReminderTriggerMinutes)
curReminderActions.add(curReminderTriggerAction)
} }
} else if (line == END_EVENT) { } else if (line == END_EVENT) {
if (curStart != -1L && curEnd == -1L) { if (curStart != -1L && curEnd == -1L) {
@@ -147,11 +155,18 @@ class IcsImporter(val activity: SimpleActivity) {
continue continue
} }
var reminders = arrayListOf(
Reminder(curReminderMinutes.getOrElse(0) { REMINDER_OFF }, curReminderActions.getOrElse(0) { REMINDER_NOTIFICATION }),
Reminder(curReminderMinutes.getOrElse(1) { REMINDER_OFF }, curReminderActions.getOrElse(1) { REMINDER_NOTIFICATION }),
Reminder(curReminderMinutes.getOrElse(2) { REMINDER_OFF }, curReminderActions.getOrElse(2) { REMINDER_NOTIFICATION })
)
reminders = reminders.filter { it.minutes != REMINDER_OFF }.sortedBy { it.minutes }.toMutableList() as ArrayList<Reminder>
val eventType = eventTypes.firstOrNull { it.id == curEventTypeId } val eventType = eventTypes.firstOrNull { it.id == curEventTypeId }
val source = if (calDAVCalendarId == 0 || eventType?.isSyncedEventType() == false) SOURCE_IMPORTED_ICS else "$CALDAV-$calDAVCalendarId" val source = if (calDAVCalendarId == 0 || eventType?.isSyncedEventType() == false) SOURCE_IMPORTED_ICS else "$CALDAV-$calDAVCalendarId"
val event = Event(null, curStart, curEnd, curTitle, curLocation, curDescription, curReminderMinutes.getOrElse(0) { -1 }, val event = Event(null, curStart, curEnd, curTitle, curLocation, curDescription, reminders[0].minutes,
curReminderMinutes.getOrElse(1) { -1 }, curReminderMinutes.getOrElse(2) { -1 }, curRepeatInterval, curRepeatRule, reminders[1].minutes, reminders[2].minutes, reminders[0].type, reminders[1].type, reminders[2].type, curRepeatInterval, curRepeatRule,
curRepeatLimit, curRepeatExceptions, curImportId, curFlags, curEventTypeId, 0, curLastModified, source) curRepeatLimit, curRepeatExceptions, "", curImportId, curFlags, curEventTypeId, 0, curLastModified, source)
if (event.getIsAllDay() && curEnd > curStart) { if (event.getIsAllDay() && curEnd > curStart) {
event.endTS -= DAY event.endTS -= DAY
@@ -269,6 +284,7 @@ class IcsImporter(val activity: SimpleActivity) {
curRecurrenceDayCode = "" curRecurrenceDayCode = ""
curFlags = 0 curFlags = 0
curReminderMinutes = ArrayList() curReminderMinutes = ArrayList()
curReminderActions = ArrayList()
curRepeatExceptions = ArrayList() curRepeatExceptions = ArrayList()
curRepeatInterval = 0 curRepeatInterval = 0
curRepeatLimit = 0L curRepeatLimit = 0L
@@ -279,6 +295,7 @@ class IcsImporter(val activity: SimpleActivity) {
isNotificationDescription = false isNotificationDescription = false
isProperReminderAction = false isProperReminderAction = false
isSequence = false isSequence = false
curReminderTriggerMinutes = -1 curReminderTriggerMinutes = REMINDER_OFF
curReminderTriggerAction = REMINDER_NOTIFICATION
} }
} }

View File

@@ -0,0 +1,5 @@
package com.simplemobiletools.calendar.pro.models
data class Attendee(val contactId: Int, var name: String, val email: String, val status: Int, var photoUri: String) {
fun getPublicName() = if (name.isNotEmpty()) name else email
}

View File

@@ -22,10 +22,14 @@ data class Event(
@ColumnInfo(name = "reminder_1_minutes") var reminder1Minutes: Int = -1, @ColumnInfo(name = "reminder_1_minutes") var reminder1Minutes: Int = -1,
@ColumnInfo(name = "reminder_2_minutes") var reminder2Minutes: Int = -1, @ColumnInfo(name = "reminder_2_minutes") var reminder2Minutes: Int = -1,
@ColumnInfo(name = "reminder_3_minutes") var reminder3Minutes: Int = -1, @ColumnInfo(name = "reminder_3_minutes") var reminder3Minutes: Int = -1,
@ColumnInfo(name = "reminder_1_type") var reminder1Type: Int = REMINDER_NOTIFICATION,
@ColumnInfo(name = "reminder_2_type") var reminder2Type: Int = REMINDER_NOTIFICATION,
@ColumnInfo(name = "reminder_3_type") var reminder3Type: Int = REMINDER_NOTIFICATION,
@ColumnInfo(name = "repeat_interval") var repeatInterval: Int = 0, @ColumnInfo(name = "repeat_interval") var repeatInterval: Int = 0,
@ColumnInfo(name = "repeat_rule") var repeatRule: Int = 0, @ColumnInfo(name = "repeat_rule") var repeatRule: Int = 0,
@ColumnInfo(name = "repeat_limit") var repeatLimit: Long = 0L, @ColumnInfo(name = "repeat_limit") var repeatLimit: Long = 0L,
@ColumnInfo(name = "repetition_exceptions") var repetitionExceptions: ArrayList<String> = ArrayList(), @ColumnInfo(name = "repetition_exceptions") var repetitionExceptions: ArrayList<String> = ArrayList(),
@ColumnInfo(name = "attendees") var attendees: String = "",
@ColumnInfo(name = "import_id") var importId: String = "", @ColumnInfo(name = "import_id") var importId: String = "",
@ColumnInfo(name = "flags") var flags: Int = 0, @ColumnInfo(name = "flags") var flags: Int = 0,
@ColumnInfo(name = "event_type") var eventType: Long = REGULAR_EVENT_TYPE_ID, @ColumnInfo(name = "event_type") var eventType: Long = REGULAR_EVENT_TYPE_ID,
@@ -80,7 +84,7 @@ data class Event(
while (newDateTime.dayOfMonth().maximumValue < Formatter.getDateTimeFromTS(original.startTS).dayOfMonth().maximumValue) { while (newDateTime.dayOfMonth().maximumValue < Formatter.getDateTimeFromTS(original.startTS).dayOfMonth().maximumValue) {
newDateTime = newDateTime.plusMonths(repeatInterval / MONTH) newDateTime = newDateTime.plusMonths(repeatInterval / MONTH)
newDateTime = newDateTime.withDayOfMonth(newDateTime.dayOfMonth().maximumValue) newDateTime = newDateTime.withDayOfMonth(currStart.dayOfMonth)
} }
return newDateTime return newDateTime
} }
@@ -116,7 +120,11 @@ data class Event(
fun getIsAllDay() = flags and FLAG_ALL_DAY != 0 fun getIsAllDay() = flags and FLAG_ALL_DAY != 0
fun getReminders() = setOf(reminder1Minutes, reminder2Minutes, reminder3Minutes).filter { it != REMINDER_OFF } fun getReminders() = setOf(
Reminder(reminder1Minutes, reminder1Type),
Reminder(reminder2Minutes, reminder2Type),
Reminder(reminder3Minutes, reminder3Type)
).filter { it.minutes != REMINDER_OFF }
// properly return the start time of all-day events as midnight // properly return the start time of all-day events as midnight
fun getEventStartTS(): Long { fun getEventStartTS(): Long {

View File

@@ -0,0 +1,3 @@
package com.simplemobiletools.calendar.pro.models
data class Reminder(val minutes: Int, val type: Int)

View File

@@ -10,6 +10,7 @@ import com.simplemobiletools.calendar.pro.extensions.scheduleNextEventReminder
import com.simplemobiletools.calendar.pro.extensions.updateListWidget import com.simplemobiletools.calendar.pro.extensions.updateListWidget
import com.simplemobiletools.calendar.pro.helpers.EVENT_ID import com.simplemobiletools.calendar.pro.helpers.EVENT_ID
import com.simplemobiletools.calendar.pro.helpers.Formatter import com.simplemobiletools.calendar.pro.helpers.Formatter
import com.simplemobiletools.calendar.pro.helpers.REMINDER_NOTIFICATION
class NotificationReceiver : BroadcastReceiver() { class NotificationReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) { override fun onReceive(context: Context, intent: Intent) {
@@ -30,7 +31,7 @@ class NotificationReceiver : BroadcastReceiver() {
context.updateListWidget() context.updateListWidget()
val event = context.eventsDB.getEventWithId(id) val event = context.eventsDB.getEventWithId(id)
if (event == null || event.getReminders().isEmpty()) { if (event == null || event.getReminders().none { it.type == REMINDER_NOTIFICATION }) {
return return
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 260 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 313 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 425 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 554 B

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/attendee_circular_background">
<shape android:shape="oval">
<solid android:color="@color/color_primary"/>
</shape>
</item>
<item
android:bottom="@dimen/medium_margin"
android:drawable="@drawable/ic_person"
android:left="@dimen/medium_margin"
android:right="@dimen/medium_margin"
android:top="@dimen/medium_margin"/>
</layer-list>

View File

@@ -50,9 +50,7 @@
android:layout_alignTop="@+id/event_location" android:layout_alignTop="@+id/event_location"
android:layout_alignBottom="@+id/event_location" android:layout_alignBottom="@+id/event_location"
android:layout_alignParentEnd="true" android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_marginEnd="@dimen/activity_margin" android:layout_marginEnd="@dimen/activity_margin"
android:layout_marginRight="@dimen/activity_margin"
android:background="?attr/selectableItemBackgroundBorderless" android:background="?attr/selectableItemBackgroundBorderless"
android:paddingStart="@dimen/small_margin" android:paddingStart="@dimen/small_margin"
android:paddingEnd="@dimen/small_margin" android:paddingEnd="@dimen/small_margin"
@@ -104,13 +102,9 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@+id/event_description_divider" android:layout_below="@+id/event_description_divider"
android:layout_alignParentEnd="true" android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_marginStart="@dimen/small_margin" android:layout_marginStart="@dimen/small_margin"
android:layout_marginLeft="@dimen/small_margin"
android:layout_marginEnd="@dimen/normal_margin" android:layout_marginEnd="@dimen/normal_margin"
android:layout_marginRight="@dimen/normal_margin"
android:layout_toEndOf="@+id/event_time_image" android:layout_toEndOf="@+id/event_time_image"
android:layout_toRightOf="@+id/event_time_image"
android:paddingTop="@dimen/normal_margin" android:paddingTop="@dimen/normal_margin"
android:paddingBottom="@dimen/normal_margin" android:paddingBottom="@dimen/normal_margin"
android:text="@string/all_day" android:text="@string/all_day"
@@ -123,11 +117,9 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@+id/event_time_image" android:layout_below="@+id/event_time_image"
android:layout_alignStart="@+id/event_all_day" android:layout_alignStart="@+id/event_all_day"
android:layout_alignLeft="@+id/event_all_day"
android:background="?attr/selectableItemBackground" android:background="?attr/selectableItemBackground"
android:paddingTop="@dimen/activity_margin" android:paddingTop="@dimen/activity_margin"
android:paddingEnd="@dimen/activity_margin" android:paddingEnd="@dimen/activity_margin"
android:paddingRight="@dimen/activity_margin"
android:paddingBottom="@dimen/activity_margin" android:paddingBottom="@dimen/activity_margin"
android:textSize="@dimen/day_text_size" android:textSize="@dimen/day_text_size"
tools:text="January 1 1970"/> tools:text="January 1 1970"/>
@@ -138,7 +130,6 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@+id/event_time_image" android:layout_below="@+id/event_time_image"
android:layout_alignParentEnd="true" android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:background="?attr/selectableItemBackground" android:background="?attr/selectableItemBackground"
android:padding="@dimen/activity_margin" android:padding="@dimen/activity_margin"
android:textSize="@dimen/day_text_size" android:textSize="@dimen/day_text_size"
@@ -150,11 +141,9 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@+id/event_start_date" android:layout_below="@+id/event_start_date"
android:layout_alignStart="@+id/event_all_day" android:layout_alignStart="@+id/event_all_day"
android:layout_alignLeft="@+id/event_all_day"
android:background="?attr/selectableItemBackground" android:background="?attr/selectableItemBackground"
android:paddingTop="@dimen/activity_margin" android:paddingTop="@dimen/activity_margin"
android:paddingEnd="@dimen/activity_margin" android:paddingEnd="@dimen/activity_margin"
android:paddingRight="@dimen/activity_margin"
android:paddingBottom="@dimen/activity_margin" android:paddingBottom="@dimen/activity_margin"
android:textSize="@dimen/day_text_size" android:textSize="@dimen/day_text_size"
tools:text="January 1 1970"/> tools:text="January 1 1970"/>
@@ -165,7 +154,6 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@+id/event_start_time" android:layout_below="@+id/event_start_time"
android:layout_alignParentEnd="true" android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:background="?attr/selectableItemBackground" android:background="?attr/selectableItemBackground"
android:padding="@dimen/activity_margin" android:padding="@dimen/activity_margin"
android:textSize="@dimen/day_text_size" android:textSize="@dimen/day_text_size"
@@ -189,7 +177,6 @@
android:layout_alignTop="@+id/event_reminder_1" android:layout_alignTop="@+id/event_reminder_1"
android:layout_alignBottom="@+id/event_reminder_1" android:layout_alignBottom="@+id/event_reminder_1"
android:layout_marginStart="@dimen/normal_margin" android:layout_marginStart="@dimen/normal_margin"
android:layout_marginLeft="@dimen/normal_margin"
android:alpha="0.8" android:alpha="0.8"
android:padding="@dimen/medium_margin" android:padding="@dimen/medium_margin"
android:src="@drawable/ic_bell"/> android:src="@drawable/ic_bell"/>
@@ -200,13 +187,28 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@+id/event_date_time_divider" android:layout_below="@+id/event_date_time_divider"
android:layout_marginStart="@dimen/small_margin" android:layout_marginStart="@dimen/small_margin"
android:layout_marginLeft="@dimen/small_margin" android:layout_toStartOf="@+id/event_reminder_1_type"
android:layout_toEndOf="@+id/event_reminder_image" android:layout_toEndOf="@+id/event_reminder_image"
android:layout_toRightOf="@+id/event_reminder_image"
android:background="?attr/selectableItemBackground" android:background="?attr/selectableItemBackground"
android:ellipsize="end"
android:lines="1"
android:paddingTop="@dimen/activity_margin" android:paddingTop="@dimen/activity_margin"
android:paddingBottom="@dimen/activity_margin" android:paddingBottom="@dimen/activity_margin"
android:textSize="@dimen/day_text_size"/> android:textSize="@dimen/day_text_size"
tools:text="@string/add_another_reminder"/>
<ImageView
android:id="@+id/event_reminder_1_type"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@+id/event_reminder_1"
android:layout_alignBottom="@+id/event_reminder_1"
android:layout_alignParentEnd="true"
android:layout_marginStart="@dimen/small_margin"
android:alpha="0.8"
android:background="?attr/selectableItemBackground"
android:padding="@dimen/activity_margin"
android:src="@drawable/ic_bell"/>
<com.simplemobiletools.commons.views.MyTextView <com.simplemobiletools.commons.views.MyTextView
android:id="@+id/event_reminder_2" android:id="@+id/event_reminder_2"
@@ -214,14 +216,30 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@+id/event_reminder_1" android:layout_below="@+id/event_reminder_1"
android:layout_alignStart="@+id/event_reminder_1" android:layout_alignStart="@+id/event_reminder_1"
android:layout_alignLeft="@+id/event_reminder_1" android:layout_toStartOf="@+id/event_reminder_2_type"
android:alpha="0.4" android:alpha="0.4"
android:background="?attr/selectableItemBackground" android:background="?attr/selectableItemBackground"
android:ellipsize="end"
android:lines="1"
android:paddingTop="@dimen/activity_margin" android:paddingTop="@dimen/activity_margin"
android:paddingBottom="@dimen/activity_margin" android:paddingBottom="@dimen/activity_margin"
android:text="@string/add_another_reminder" android:text="@string/add_another_reminder"
android:textSize="@dimen/day_text_size" android:textSize="@dimen/day_text_size"
android:visibility="gone"/> android:visibility="gone"
tools:text="@string/add_another_reminder"/>
<ImageView
android:id="@+id/event_reminder_2_type"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@+id/event_reminder_2"
android:layout_alignBottom="@+id/event_reminder_2"
android:layout_alignParentEnd="true"
android:layout_marginStart="@dimen/small_margin"
android:alpha="0.8"
android:background="?attr/selectableItemBackground"
android:padding="@dimen/activity_margin"
android:src="@drawable/ic_bell"/>
<com.simplemobiletools.commons.views.MyTextView <com.simplemobiletools.commons.views.MyTextView
android:id="@+id/event_reminder_3" android:id="@+id/event_reminder_3"
@@ -229,14 +247,30 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@+id/event_reminder_2" android:layout_below="@+id/event_reminder_2"
android:layout_alignStart="@+id/event_reminder_1" android:layout_alignStart="@+id/event_reminder_1"
android:layout_alignLeft="@+id/event_reminder_1" android:layout_toStartOf="@+id/event_reminder_3_type"
android:alpha="0.4" android:alpha="0.4"
android:background="?attr/selectableItemBackground" android:background="?attr/selectableItemBackground"
android:ellipsize="end"
android:lines="1"
android:paddingTop="@dimen/activity_margin" android:paddingTop="@dimen/activity_margin"
android:paddingBottom="@dimen/activity_margin" android:paddingBottom="@dimen/activity_margin"
android:text="@string/add_another_reminder" android:text="@string/add_another_reminder"
android:textSize="@dimen/day_text_size" android:textSize="@dimen/day_text_size"
android:visibility="gone"/> android:visibility="gone"
tools:text="@string/add_another_reminder"/>
<ImageView
android:id="@+id/event_reminder_3_type"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@+id/event_reminder_3"
android:layout_alignBottom="@+id/event_reminder_3"
android:layout_alignParentEnd="true"
android:layout_marginStart="@dimen/small_margin"
android:alpha="0.8"
android:background="?attr/selectableItemBackground"
android:padding="@dimen/activity_margin"
android:src="@drawable/ic_bell"/>
<ImageView <ImageView
android:id="@+id/event_reminder_divider" android:id="@+id/event_reminder_divider"
@@ -256,7 +290,6 @@
android:layout_alignTop="@+id/event_repetition" android:layout_alignTop="@+id/event_repetition"
android:layout_alignBottom="@+id/event_repetition" android:layout_alignBottom="@+id/event_repetition"
android:layout_marginStart="@dimen/normal_margin" android:layout_marginStart="@dimen/normal_margin"
android:layout_marginLeft="@dimen/normal_margin"
android:alpha="0.8" android:alpha="0.8"
android:padding="@dimen/medium_margin" android:padding="@dimen/medium_margin"
android:src="@drawable/ic_repeat"/> android:src="@drawable/ic_repeat"/>
@@ -267,13 +300,12 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@+id/event_reminder_divider" android:layout_below="@+id/event_reminder_divider"
android:layout_marginStart="@dimen/small_margin" android:layout_marginStart="@dimen/small_margin"
android:layout_marginLeft="@dimen/small_margin"
android:layout_toEndOf="@+id/event_repetition_image" android:layout_toEndOf="@+id/event_repetition_image"
android:layout_toRightOf="@+id/event_repetition_image"
android:background="?attr/selectableItemBackground" android:background="?attr/selectableItemBackground"
android:paddingTop="@dimen/normal_margin" android:paddingTop="@dimen/normal_margin"
android:paddingBottom="@dimen/normal_margin" android:paddingBottom="@dimen/normal_margin"
android:textSize="@dimen/day_text_size"/> android:textSize="@dimen/day_text_size"
tools:text="@string/no_repetition"/>
<RelativeLayout <RelativeLayout
android:id="@+id/event_repetition_rule_holder" android:id="@+id/event_repetition_rule_holder"
@@ -281,7 +313,6 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@+id/event_repetition" android:layout_below="@+id/event_repetition"
android:layout_alignStart="@+id/event_repetition" android:layout_alignStart="@+id/event_repetition"
android:layout_alignLeft="@+id/event_repetition"
android:background="?attr/selectableItemBackground" android:background="?attr/selectableItemBackground"
android:visibility="gone"> android:visibility="gone">
@@ -300,9 +331,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentEnd="true" android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_toEndOf="@+id/event_repetition_rule_label" android:layout_toEndOf="@+id/event_repetition_rule_label"
android:layout_toRightOf="@+id/event_repetition_rule_label"
android:clickable="false" android:clickable="false"
android:gravity="end" android:gravity="end"
android:padding="@dimen/activity_margin" android:padding="@dimen/activity_margin"
@@ -316,7 +345,6 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@+id/event_repetition_rule_holder" android:layout_below="@+id/event_repetition_rule_holder"
android:layout_alignStart="@+id/event_repetition" android:layout_alignStart="@+id/event_repetition"
android:layout_alignLeft="@+id/event_repetition"
android:background="?attr/selectableItemBackground" android:background="?attr/selectableItemBackground"
android:visibility="gone"> android:visibility="gone">
@@ -325,7 +353,6 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_toStartOf="@+id/event_repetition_limit" android:layout_toStartOf="@+id/event_repetition_limit"
android:layout_toLeftOf="@+id/event_repetition_limit"
android:clickable="false" android:clickable="false"
android:paddingTop="@dimen/activity_margin" android:paddingTop="@dimen/activity_margin"
android:paddingBottom="@dimen/activity_margin" android:paddingBottom="@dimen/activity_margin"
@@ -337,7 +364,6 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentEnd="true" android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:clickable="false" android:clickable="false"
android:padding="@dimen/activity_margin" android:padding="@dimen/activity_margin"
android:text="@string/forever" android:text="@string/forever"
@@ -354,14 +380,43 @@
android:importantForAccessibility="no"/> android:importantForAccessibility="no"/>
<ImageView <ImageView
android:id="@+id/event_caldav_calendar_image" android:id="@+id/event_attendees_image"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_below="@+id/event_repetition_divider" android:layout_below="@+id/event_repetition_divider"
android:layout_alignTop="@+id/event_attendees_holder"
android:layout_marginStart="@dimen/normal_margin"
android:layout_marginTop="@dimen/small_margin"
android:alpha="0.8"
android:padding="@dimen/medium_margin"
android:src="@drawable/ic_people"/>
<LinearLayout
android:id="@+id/event_attendees_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/event_repetition_divider"
android:layout_marginTop="@dimen/medium_margin"
android:layout_toEndOf="@+id/event_attendees_image"
android:orientation="vertical"/>
<ImageView
android:id="@+id/event_attendees_divider"
android:layout_width="match_parent"
android:layout_height="1px"
android:layout_below="@+id/event_attendees_holder"
android:layout_marginTop="@dimen/medium_margin"
android:background="@color/divider_grey"
android:importantForAccessibility="no"/>
<ImageView
android:id="@+id/event_caldav_calendar_image"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_below="@+id/event_attendees_divider"
android:layout_alignTop="@+id/event_caldav_calendar_holder" android:layout_alignTop="@+id/event_caldav_calendar_holder"
android:layout_alignBottom="@+id/event_caldav_calendar_holder" android:layout_alignBottom="@+id/event_caldav_calendar_holder"
android:layout_marginStart="@dimen/normal_margin" android:layout_marginStart="@dimen/normal_margin"
android:layout_marginLeft="@dimen/normal_margin"
android:alpha="0.8" android:alpha="0.8"
android:padding="@dimen/medium_margin" android:padding="@dimen/medium_margin"
android:src="@drawable/ic_calendar" android:src="@drawable/ic_calendar"
@@ -371,9 +426,8 @@
android:id="@+id/event_caldav_calendar_holder" android:id="@+id/event_caldav_calendar_holder"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@+id/event_repetition_divider" android:layout_below="@+id/event_attendees_divider"
android:layout_toEndOf="@+id/event_caldav_calendar_image" android:layout_toEndOf="@+id/event_caldav_calendar_image"
android:layout_toRightOf="@+id/event_caldav_calendar_image"
android:background="?attr/selectableItemBackground" android:background="?attr/selectableItemBackground"
android:visibility="gone"> android:visibility="gone">
@@ -382,7 +436,6 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="@dimen/small_margin" android:layout_marginStart="@dimen/small_margin"
android:layout_marginLeft="@dimen/small_margin"
android:layout_toStartOf="@+id/event_caldav_calendar_color" android:layout_toStartOf="@+id/event_caldav_calendar_color"
android:ellipsize="end" android:ellipsize="end"
android:maxLines="1" android:maxLines="1"
@@ -398,7 +451,6 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@+id/event_caldav_calendar_name" android:layout_below="@+id/event_caldav_calendar_name"
android:layout_marginStart="@dimen/small_margin" android:layout_marginStart="@dimen/small_margin"
android:layout_marginLeft="@dimen/small_margin"
android:layout_toStartOf="@+id/event_caldav_calendar_color" android:layout_toStartOf="@+id/event_caldav_calendar_color"
android:ellipsize="end" android:ellipsize="end"
android:maxLines="1" android:maxLines="1"
@@ -412,10 +464,8 @@
android:layout_width="@dimen/color_sample_size" android:layout_width="@dimen/color_sample_size"
android:layout_height="@dimen/color_sample_size" android:layout_height="@dimen/color_sample_size"
android:layout_alignParentEnd="true" android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_centerVertical="true" android:layout_centerVertical="true"
android:layout_marginEnd="@dimen/activity_margin" android:layout_marginEnd="@dimen/activity_margin"
android:layout_marginRight="@dimen/activity_margin"
android:clickable="false"/> android:clickable="false"/>
</RelativeLayout> </RelativeLayout>
@@ -437,7 +487,6 @@
android:layout_alignTop="@+id/event_type_holder" android:layout_alignTop="@+id/event_type_holder"
android:layout_alignBottom="@+id/event_type_holder" android:layout_alignBottom="@+id/event_type_holder"
android:layout_marginStart="@dimen/normal_margin" android:layout_marginStart="@dimen/normal_margin"
android:layout_marginLeft="@dimen/normal_margin"
android:alpha="0.8" android:alpha="0.8"
android:padding="@dimen/medium_margin" android:padding="@dimen/medium_margin"
android:src="@drawable/ic_color"/> android:src="@drawable/ic_color"/>
@@ -450,7 +499,6 @@
android:layout_marginTop="@dimen/medium_margin" android:layout_marginTop="@dimen/medium_margin"
android:layout_marginBottom="@dimen/medium_margin" android:layout_marginBottom="@dimen/medium_margin"
android:layout_toEndOf="@+id/event_type_image" android:layout_toEndOf="@+id/event_type_image"
android:layout_toRightOf="@+id/event_type_image"
android:background="?attr/selectableItemBackground"> android:background="?attr/selectableItemBackground">
<com.simplemobiletools.commons.views.MyTextView <com.simplemobiletools.commons.views.MyTextView
@@ -469,10 +517,8 @@
android:layout_width="@dimen/color_sample_size" android:layout_width="@dimen/color_sample_size"
android:layout_height="@dimen/color_sample_size" android:layout_height="@dimen/color_sample_size"
android:layout_alignParentEnd="true" android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_centerVertical="true" android:layout_centerVertical="true"
android:layout_marginEnd="@dimen/activity_margin" android:layout_marginEnd="@dimen/activity_margin"
android:layout_marginRight="@dimen/activity_margin"
android:clickable="false"/> android:clickable="false"/>
</RelativeLayout> </RelativeLayout>

View File

@@ -0,0 +1,59 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/set_reminders_holder_dialog_holder"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingTop="@dimen/activity_margin"
android:paddingEnd="@dimen/activity_margin">
<ImageView
android:id="@+id/set_reminders_image"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignTop="@+id/set_reminders_1"
android:layout_alignBottom="@+id/set_reminders_1"
android:layout_marginStart="@dimen/normal_margin"
android:alpha="0.8"
android:padding="@dimen/medium_margin"
android:src="@drawable/ic_bell"/>
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/set_reminders_1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/small_margin"
android:layout_toEndOf="@+id/set_reminders_image"
android:background="?attr/selectableItemBackground"
android:paddingTop="@dimen/activity_margin"
android:paddingBottom="@dimen/activity_margin"
android:textSize="@dimen/day_text_size"/>
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/set_reminders_2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/set_reminders_1"
android:layout_alignStart="@+id/set_reminders_1"
android:background="?attr/selectableItemBackground"
android:paddingTop="@dimen/activity_margin"
android:paddingBottom="@dimen/activity_margin"
android:text="@string/add_another_reminder"
android:textSize="@dimen/day_text_size"
android:visibility="gone"/>
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/set_reminders_3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/set_reminders_2"
android:layout_alignStart="@+id/set_reminders_1"
android:background="?attr/selectableItemBackground"
android:paddingTop="@dimen/activity_margin"
android:paddingBottom="@dimen/activity_margin"
android:text="@string/add_another_reminder"
android:textSize="@dimen/day_text_size"
android:visibility="gone"/>
</RelativeLayout>

View File

@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/event_attendee_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="@dimen/medium_margin"
android:paddingBottom="@dimen/medium_margin">
<com.simplemobiletools.commons.views.MyAutoCompleteTextView
android:id="@+id/event_attendee"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginEnd="@dimen/activity_margin"
android:completionThreshold="2"
android:hint="@string/add_another_attendee"
android:lines="1"
android:maxLines="1"
android:singleLine="true"
android:textCursorDrawable="@null"
android:textSize="@dimen/bigger_text_size"/>
</RelativeLayout>

View File

@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/item_autocomplete_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="@dimen/small_margin"
android:paddingTop="@dimen/medium_margin"
android:paddingEnd="@dimen/medium_margin"
android:paddingBottom="@dimen/medium_margin">
<ImageView
android:id="@+id/item_autocomplete_image"
android:layout_width="@dimen/avatar_size"
android:layout_height="@dimen/avatar_size"
android:layout_margin="@dimen/tiny_margin"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<TextView
android:id="@+id/item_autocomplete_email"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:lines="1"
android:maxLines="1"
android:paddingStart="@dimen/medium_margin"
android:singleLine="true"
android:textSize="@dimen/bigger_text_size"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/item_autocomplete_image"
app:layout_constraintTop_toTopOf="parent"
tools:text="hello@simplemobiletools.com"/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,56 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/item_autocomplete_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="@dimen/small_margin"
android:paddingTop="@dimen/medium_margin"
android:paddingEnd="@dimen/medium_margin"
android:paddingBottom="@dimen/medium_margin">
<ImageView
android:id="@+id/item_autocomplete_image"
android:layout_width="@dimen/avatar_size"
android:layout_height="@dimen/avatar_size"
android:layout_margin="@dimen/tiny_margin"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<TextView
android:id="@+id/item_autocomplete_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:lines="1"
android:maxLines="1"
android:paddingStart="@dimen/medium_margin"
android:singleLine="true"
android:textSize="@dimen/bigger_text_size"
app:layout_constraintBottom_toTopOf="@+id/item_autocomplete_email"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/item_autocomplete_image"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed"
tools:text="Simple Mobile"/>
<TextView
android:id="@+id/item_autocomplete_email"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_below="@+id/item_autocomplete_name"
android:layout_marginEnd="8dp"
android:alpha="0.8"
android:lines="1"
android:maxLines="1"
android:paddingStart="@dimen/medium_margin"
android:singleLine="true"
android:textSize="@dimen/normal_text_size"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/item_autocomplete_image"
app:layout_constraintTop_toBottomOf="@+id/item_autocomplete_name"
tools:text="hello@simplemobiletools.com"/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -27,6 +27,10 @@
android:icon="@drawable/ic_repeat" android:icon="@drawable/ic_repeat"
android:title="@string/refresh_caldav_calendars" android:title="@string/refresh_caldav_calendars"
app:showAsAction="ifRoom"/> app:showAsAction="ifRoom"/>
<item
android:id="@+id/go_to_date"
android:title="@string/go_to_date"
app:showAsAction="never"/>
<item <item
android:id="@+id/add_holidays" android:id="@+id/add_holidays"
android:title="@string/add_holidays" android:title="@string/add_holidays"

View File

@@ -10,6 +10,7 @@
<string name="simple_event_list">لائحة أحداث بسيطة</string> <string name="simple_event_list">لائحة أحداث بسيطة</string>
<string name="no_upcoming_events">Seems like you don\'t have any upcoming events.</string> <string name="no_upcoming_events">Seems like you don\'t have any upcoming events.</string>
<string name="go_to_today">الذهاب الى اليوم</string> <string name="go_to_today">الذهاب الى اليوم</string>
<string name="go_to_date">Go to date</string>
<!-- Widget titles --> <!-- Widget titles -->
<string name="widget_monthly">تقويم شهري</string> <string name="widget_monthly">تقويم شهري</string>
@@ -97,6 +98,9 @@
<string name="add_another_reminder">إضافة تذكير آخر</string> <string name="add_another_reminder">إضافة تذكير آخر</string>
<string name="event_reminders">تذكيرات الحدث</string> <string name="event_reminders">تذكيرات الحدث</string>
<!-- Event attendees -->
<string name="add_another_attendee">Add another attendee</string>
<!-- Export / Import --> <!-- Export / Import -->
<string name="import_events">إستيراد الأحداث</string> <string name="import_events">إستيراد الأحداث</string>
<string name="export_events">تصدير الأحداث</string> <string name="export_events">تصدير الأحداث</string>
@@ -224,7 +228,7 @@
<!-- Strings displayed only on Google Playstore. Optional, but good to have --> <!-- Strings displayed only on Google Playstore. Optional, but good to have -->
<!-- Short description has to have less than 80 chars --> <!-- Short description has to have less than 80 chars -->
<string name="app_short_description">Offline kalendár pre vaše udalosti bez reklám, rešpektujúca vaše súkromie.</string> <string name="app_short_description">An offline calendar for your events without ads, respecting your privacy.</string>
<string name="app_long_description"> <string name="app_long_description">
A simple calendar with optional CalDAV synchronization. You can easily create recurring events and setup reminders, it can also display week numbers. A simple calendar with optional CalDAV synchronization. You can easily create recurring events and setup reminders, it can also display week numbers.

View File

@@ -10,6 +10,7 @@
<string name="simple_event_list">Sadə hadisələr siyahısı</string> <string name="simple_event_list">Sadə hadisələr siyahısı</string>
<string name="no_upcoming_events">Deyəsən yaxınlarda heçbir hadisə yoxdur.</string> <string name="no_upcoming_events">Deyəsən yaxınlarda heçbir hadisə yoxdur.</string>
<string name="go_to_today">Bugünə get</string> <string name="go_to_today">Bugünə get</string>
<string name="go_to_date">Go to date</string>
<!-- Widget titles --> <!-- Widget titles -->
<string name="widget_monthly">Aylıq Təqvim</string> <string name="widget_monthly">Aylıq Təqvim</string>
@@ -97,6 +98,9 @@
<string name="add_another_reminder">Başqa bir xatırladıcı əlavə et</string> <string name="add_another_reminder">Başqa bir xatırladıcı əlavə et</string>
<string name="event_reminders">Hadisə xatırladıcıları</string> <string name="event_reminders">Hadisə xatırladıcıları</string>
<!-- Event attendees -->
<string name="add_another_attendee">Add another attendee</string>
<!-- Export / Import --> <!-- Export / Import -->
<string name="import_events">Hadisələri daxil et</string> <string name="import_events">Hadisələri daxil et</string>
<string name="export_events">Hadisələri xaric et</string> <string name="export_events">Hadisələri xaric et</string>

View File

@@ -10,6 +10,7 @@
<string name="simple_event_list">Roll darvoudoù een</string> <string name="simple_event_list">Roll darvoudoù een</string>
<string name="no_upcoming_events">War a-seblant n\'ho peus darvoud ebet da zont.</string> <string name="no_upcoming_events">War a-seblant n\'ho peus darvoud ebet da zont.</string>
<string name="go_to_today">Mont da hiziv</string> <string name="go_to_today">Mont da hiziv</string>
<string name="go_to_date">Go to date</string>
<!-- Widget titles --> <!-- Widget titles -->
<string name="widget_monthly">Deiziataer miziek</string> <string name="widget_monthly">Deiziataer miziek</string>
@@ -97,6 +98,9 @@
<string name="add_another_reminder">Ouzhpennañ un adc\'halv all</string> <string name="add_another_reminder">Ouzhpennañ un adc\'halv all</string>
<string name="event_reminders">Event reminders</string> <string name="event_reminders">Event reminders</string>
<!-- Event attendees -->
<string name="add_another_attendee">Add another attendee</string>
<!-- Export / Import --> <!-- Export / Import -->
<string name="import_events">Enporzhiañ darvoudoù</string> <string name="import_events">Enporzhiañ darvoudoù</string>
<string name="export_events">Ezporzhiañ darvoudoù</string> <string name="export_events">Ezporzhiañ darvoudoù</string>

View File

@@ -10,6 +10,7 @@
<string name="simple_event_list">Jednoduchý seznam událostí</string> <string name="simple_event_list">Jednoduchý seznam událostí</string>
<string name="no_upcoming_events">Nemáte žádné nadcházející události.</string> <string name="no_upcoming_events">Nemáte žádné nadcházející události.</string>
<string name="go_to_today">Přejít na dnešek</string> <string name="go_to_today">Přejít na dnešek</string>
<string name="go_to_date">Go to date</string>
<!-- Widget titles --> <!-- Widget titles -->
<string name="widget_monthly">Měsíční kalendář</string> <string name="widget_monthly">Měsíční kalendář</string>
@@ -97,6 +98,9 @@
<string name="add_another_reminder">Přidat další připomínku</string> <string name="add_another_reminder">Přidat další připomínku</string>
<string name="event_reminders">Připomínky událostí</string> <string name="event_reminders">Připomínky událostí</string>
<!-- Event attendees -->
<string name="add_another_attendee">Add another attendee</string>
<!-- Export / Import --> <!-- Export / Import -->
<string name="import_events">Import událostí</string> <string name="import_events">Import událostí</string>
<string name="export_events">Export událostí</string> <string name="export_events">Export událostí</string>

View File

@@ -10,6 +10,7 @@
<string name="simple_event_list">Begivenhedsliste</string> <string name="simple_event_list">Begivenhedsliste</string>
<string name="no_upcoming_events">Du ser ikke ud til at have nogen forestående begivenheder.</string> <string name="no_upcoming_events">Du ser ikke ud til at have nogen forestående begivenheder.</string>
<string name="go_to_today">Gå til i dag</string> <string name="go_to_today">Gå til i dag</string>
<string name="go_to_date">Gå til dato</string>
<!-- Widget titles --> <!-- Widget titles -->
<string name="widget_monthly">Månedlig kalender</string> <string name="widget_monthly">Månedlig kalender</string>
@@ -97,6 +98,9 @@
<string name="add_another_reminder">Tilføj en påmindelse mere</string> <string name="add_another_reminder">Tilføj en påmindelse mere</string>
<string name="event_reminders">Påmindelser</string> <string name="event_reminders">Påmindelser</string>
<!-- Event attendees -->
<string name="add_another_attendee">Tilføj en anden deltager</string>
<!-- Export / Import --> <!-- Export / Import -->
<string name="import_events">Importer begivenheder</string> <string name="import_events">Importer begivenheder</string>
<string name="export_events">Eksporter begivenheder</string> <string name="export_events">Eksporter begivenheder</string>
@@ -169,13 +173,13 @@
<string name="default_reminder_2">Påmindelse 2</string> <string name="default_reminder_2">Påmindelse 2</string>
<string name="default_reminder_3">Påmindelse 3</string> <string name="default_reminder_3">Påmindelse 3</string>
<string name="view_to_open_from_widget">Visning til brug i widget\'en</string> <string name="view_to_open_from_widget">Visning til brug i widget\'en</string>
<string name="last_view">Last view</string> <string name="last_view">Seneste visning</string>
<string name="new_events">New events</string> <string name="new_events">Nye begivenheder</string>
<string name="default_start_time">Default start time</string> <string name="default_start_time">Standard starttidspunkt</string>
<string name="next_full_hour">Next full hour</string> <string name="next_full_hour">Næste hele time</string>
<string name="default_duration">Default duration</string> <string name="default_duration">Standard varighed</string>
<string name="last_used_one">Last used one</string> <string name="last_used_one">Senest brugte</string>
<string name="other_time">Other time</string> <string name="other_time">Anden tid</string>
<!-- CalDAV sync --> <!-- CalDAV sync -->
<string name="caldav">CalDAV</string> <string name="caldav">CalDAV</string>

View File

@@ -10,6 +10,7 @@
<string name="simple_event_list">Einfache Terminliste</string> <string name="simple_event_list">Einfache Terminliste</string>
<string name="no_upcoming_events">Scheint so, als hättest du keine anstehenden Termine.</string> <string name="no_upcoming_events">Scheint so, als hättest du keine anstehenden Termine.</string>
<string name="go_to_today">Springe zu Heute</string> <string name="go_to_today">Springe zu Heute</string>
<string name="go_to_date">Go to date</string>
<!-- Widget titles --> <!-- Widget titles -->
<string name="widget_monthly">Monatskalender</string> <string name="widget_monthly">Monatskalender</string>
@@ -97,6 +98,9 @@
<string name="add_another_reminder">Weitere Erinnerung hinzufügen</string> <string name="add_another_reminder">Weitere Erinnerung hinzufügen</string>
<string name="event_reminders">Termin-Erinnerungen</string> <string name="event_reminders">Termin-Erinnerungen</string>
<!-- Event attendees -->
<string name="add_another_attendee">Add another attendee</string>
<!-- Export / Import --> <!-- Export / Import -->
<string name="import_events">Termine importieren</string> <string name="import_events">Termine importieren</string>
<string name="export_events">Termine exportieren</string> <string name="export_events">Termine exportieren</string>

View File

@@ -9,7 +9,8 @@
<string name="yearly_view">Ετήσια προβολή</string> <string name="yearly_view">Ετήσια προβολή</string>
<string name="simple_event_list">Απλή λίστα εκδηλώσεων</string> <string name="simple_event_list">Απλή λίστα εκδηλώσεων</string>
<string name="no_upcoming_events">Φαίνεται πως δεν έχετε επερχόμενες εκδηλώσεις.</string> <string name="no_upcoming_events">Φαίνεται πως δεν έχετε επερχόμενες εκδηλώσεις.</string>
<string name="go_to_today">Πηγαίνετε στο σήμερα</string> <string name="go_to_today">Μετάβαση στο σήμερα</string>
<string name="go_to_date">Μετάβαση σε ημερ/νία</string>
<!-- Widget titles --> <!-- Widget titles -->
<string name="widget_monthly">Μηνιαίο ημερολόγιο</string> <string name="widget_monthly">Μηνιαίο ημερολόγιο</string>
@@ -49,7 +50,7 @@
<string name="update_one_only">Ενημέρωση μόνο του επιλεγμένου περιστατικού</string> <string name="update_one_only">Ενημέρωση μόνο του επιλεγμένου περιστατικού</string>
<string name="update_all_occurrences">Ενημέρωση όλων των περιστατικών</string> <string name="update_all_occurrences">Ενημέρωση όλων των περιστατικών</string>
<string name="repeat_till_date">Επαναλάβετε μέχρι μια ημερομηνία</string> <string name="repeat_till_date">Επαναλάβετε μέχρι μια ημερομηνία</string>
<string name="stop_repeating_after_x">Stop repeating after x occurrences</string> <string name="stop_repeating_after_x">Παύση επαναλήψεων μετά από x εμφανίσεις</string>
<string name="repeat_forever">Επαναλάβετε για πάντα</string> <string name="repeat_forever">Επαναλάβετε για πάντα</string>
<string name="times">times</string> <string name="times">times</string>
<string name="repeat">Επανάληψη</string> <string name="repeat">Επανάληψη</string>
@@ -58,9 +59,9 @@
<string name="selected_days">Σε επιλεγμένες μέρες</string> <string name="selected_days">Σε επιλεγμένες μέρες</string>
<string name="the_same_day">Την ίδια μέρα</string> <string name="the_same_day">Την ίδια μέρα</string>
<string name="the_last_day">Την τελευταία μέρα</string> <string name="the_last_day">Την τελευταία μέρα</string>
<string name="repeat_on_the_same_day_monthly">Επαναλάβετε την ίδια ημέρα κάθε μήνα</string> <string name="repeat_on_the_same_day_monthly">Επανάληψη την ίδια ημέρα κάθε μήνα</string>
<string name="repeat_on_the_last_day_monthly">Επαναλάβετε την τελευταία ημέρα του μήνα</string> <string name="repeat_on_the_last_day_monthly">Επανάληψη την τελευταία ημέρα του μήνα</string>
<string name="repeat_on_the_same_day_yearly">Επαναλάβετε την τελευταία ημέρα του μήνα</string> <string name="repeat_on_the_same_day_yearly">Επανάληψη την τελευταία ημέρα του έτους</string>
<string name="repeat_every_m">Επανάληψη κάθε</string> <string name="repeat_every_m">Επανάληψη κάθε</string>
<string name="every_m">Κάθε</string> <string name="every_m">Κάθε</string>
<string name="first_m">πρώτη</string> <string name="first_m">πρώτη</string>
@@ -97,6 +98,9 @@
<string name="add_another_reminder">Προσθέστε μια άλλη υπενθύμιση</string> <string name="add_another_reminder">Προσθέστε μια άλλη υπενθύμιση</string>
<string name="event_reminders">Υπενθυμίσεις εκδηλώσεων</string> <string name="event_reminders">Υπενθυμίσεις εκδηλώσεων</string>
<!-- Event attendees -->
<string name="add_another_attendee">Προσθήκη άλλης συμμετοχής</string>
<!-- Export / Import --> <!-- Export / Import -->
<string name="import_events">Εισαγωγή εκδηλώσεων</string> <string name="import_events">Εισαγωγή εκδηλώσεων</string>
<string name="export_events">Εξαγωγή εκδηλώσεων</string> <string name="export_events">Εξαγωγή εκδηλώσεων</string>
@@ -168,14 +172,14 @@
<string name="default_reminder_1">Προεπιλογή υπενθύμισης 1</string> <string name="default_reminder_1">Προεπιλογή υπενθύμισης 1</string>
<string name="default_reminder_2">Προεπιλογή υπενθύμισης 2</string> <string name="default_reminder_2">Προεπιλογή υπενθύμισης 2</string>
<string name="default_reminder_3">Προεπιλογή υπενθύμισης 3</string> <string name="default_reminder_3">Προεπιλογή υπενθύμισης 3</string>
<string name="view_to_open_from_widget">Προβολή για να ανοίξετε από το widget λίστας συμβάντων</string> <string name="view_to_open_from_widget">Προβολή για άνοιγμα από το widget λίστας συμβάντων</string>
<string name="last_view">Τελευταία προβολή</string> <string name="last_view">Τελευταία προβολή</string>
<string name="new_events">Νέα γεγονότα</string> <string name="new_events">Νέα γεγονότα</string>
<string name="default_start_time">Προεπιλεγμένη ώρα έναρξης</string> <string name="default_start_time">Προεπιλεγμένη ώρα έναρξης</string>
<string name="next_full_hour">Την επόμενη πλήρη ώρα</string> <string name="next_full_hour">Την επόμενη πλήρη ώρα</string>
<string name="default_duration">Προεπιλεγμένη διάρκεια</string> <string name="default_duration">Προεπιλεγμένη διάρκεια</string>
<string name="last_used_one">Τελευταία χρήση</string> <string name="last_used_one">Τελευταία χρήση</string>
<string name="other_time">Other time</string> <string name="other_time">Άλλη ώρα</string>
<!-- CalDAV sync --> <!-- CalDAV sync -->
<string name="caldav">CalDAV</string> <string name="caldav">CalDAV</string>

View File

@@ -10,6 +10,7 @@
<string name="simple_event_list">Lista de eventos sencilla</string> <string name="simple_event_list">Lista de eventos sencilla</string>
<string name="no_upcoming_events">Parece que no tienes ningún evento próximo.</string> <string name="no_upcoming_events">Parece que no tienes ningún evento próximo.</string>
<string name="go_to_today">Ir al día de hoy</string> <string name="go_to_today">Ir al día de hoy</string>
<string name="go_to_date">Go to date</string>
<!-- Widget titles --> <!-- Widget titles -->
<string name="widget_monthly">Calendario mensual</string> <string name="widget_monthly">Calendario mensual</string>
@@ -97,6 +98,9 @@
<string name="add_another_reminder">Agregar otro recordatorio</string> <string name="add_another_reminder">Agregar otro recordatorio</string>
<string name="event_reminders">Recordatorio de eventos</string> <string name="event_reminders">Recordatorio de eventos</string>
<!-- Event attendees -->
<string name="add_another_attendee">Add another attendee</string>
<!-- Export / Import --> <!-- Export / Import -->
<string name="import_events">Importar eventos</string> <string name="import_events">Importar eventos</string>
<string name="export_events">Exportar eventos</string> <string name="export_events">Exportar eventos</string>

View File

@@ -10,6 +10,7 @@
<string name="simple_event_list">Liste simple d\'événements</string> <string name="simple_event_list">Liste simple d\'événements</string>
<string name="no_upcoming_events">Il semblerait que vous n\'ayez aucun événement à venir.</string> <string name="no_upcoming_events">Il semblerait que vous n\'ayez aucun événement à venir.</string>
<string name="go_to_today">Aller à aujourd\'hui</string> <string name="go_to_today">Aller à aujourd\'hui</string>
<string name="go_to_date">Go to date</string>
<!-- Widget titles --> <!-- Widget titles -->
<string name="widget_monthly">Calendrier mensuel</string> <string name="widget_monthly">Calendrier mensuel</string>
@@ -97,6 +98,9 @@
<string name="add_another_reminder">Ajouter un autre rappel</string> <string name="add_another_reminder">Ajouter un autre rappel</string>
<string name="event_reminders">Rappels d\'événements</string> <string name="event_reminders">Rappels d\'événements</string>
<!-- Event attendees -->
<string name="add_another_attendee">Add another attendee</string>
<!-- Export / Import --> <!-- Export / Import -->
<string name="import_events">Importer des événements</string> <string name="import_events">Importer des événements</string>
<string name="export_events">Exporter des événements</string> <string name="export_events">Exporter des événements</string>

View File

@@ -10,6 +10,7 @@
<string name="simple_event_list">Lista de eventos simple</string> <string name="simple_event_list">Lista de eventos simple</string>
<string name="no_upcoming_events">Semella que non ten ningún evento próximo.</string> <string name="no_upcoming_events">Semella que non ten ningún evento próximo.</string>
<string name="go_to_today">Ir ao día de hoxe</string> <string name="go_to_today">Ir ao día de hoxe</string>
<string name="go_to_date">Go to date</string>
<!-- Widget titles --> <!-- Widget titles -->
<string name="widget_monthly">Calendario mensual</string> <string name="widget_monthly">Calendario mensual</string>
@@ -97,6 +98,9 @@
<string name="add_another_reminder">Engadir outro recordatorio</string> <string name="add_another_reminder">Engadir outro recordatorio</string>
<string name="event_reminders">Recordatorios de eventos</string> <string name="event_reminders">Recordatorios de eventos</string>
<!-- Event attendees -->
<string name="add_another_attendee">Add another attendee</string>
<!-- Export / Import --> <!-- Export / Import -->
<string name="import_events">Importar eventos</string> <string name="import_events">Importar eventos</string>
<string name="export_events">Exportar eventos</string> <string name="export_events">Exportar eventos</string>

View File

@@ -10,6 +10,7 @@
<string name="simple_event_list">सरल इवेंट सूची</string> <string name="simple_event_list">सरल इवेंट सूची</string>
<string name="no_upcoming_events">Seems like you don\'t have any upcoming events.</string> <string name="no_upcoming_events">Seems like you don\'t have any upcoming events.</string>
<string name="go_to_today">Go to today</string> <string name="go_to_today">Go to today</string>
<string name="go_to_date">Go to date</string>
<!-- Widget titles --> <!-- Widget titles -->
<string name="widget_monthly">Calendar monthly</string> <string name="widget_monthly">Calendar monthly</string>
@@ -98,6 +99,9 @@
<string name="add_another_reminder">Add another reminder</string> <string name="add_another_reminder">Add another reminder</string>
<string name="event_reminders">Event reminders</string> <string name="event_reminders">Event reminders</string>
<!-- Event attendees -->
<string name="add_another_attendee">Add another attendee</string>
<!-- Export / Import --> <!-- Export / Import -->
<string name="import_events">Import events</string> <string name="import_events">Import events</string>
<string name="export_events">Export events</string> <string name="export_events">Export events</string>

View File

@@ -10,6 +10,7 @@
<string name="simple_event_list">Jednostavan popis događaja</string> <string name="simple_event_list">Jednostavan popis događaja</string>
<string name="no_upcoming_events">Izgleda da nemate nadolazećih događaja.</string> <string name="no_upcoming_events">Izgleda da nemate nadolazećih događaja.</string>
<string name="go_to_today">Idi na danas</string> <string name="go_to_today">Idi na danas</string>
<string name="go_to_date">Go to date</string>
<!-- Widget titles --> <!-- Widget titles -->
<string name="widget_monthly">Mjesečni raspored</string> <string name="widget_monthly">Mjesečni raspored</string>
@@ -97,6 +98,9 @@
<string name="add_another_reminder">Dodaj još jedan podsjetnik</string> <string name="add_another_reminder">Dodaj još jedan podsjetnik</string>
<string name="event_reminders">Podsjetnici na događaj</string> <string name="event_reminders">Podsjetnici na događaj</string>
<!-- Event attendees -->
<string name="add_another_attendee">Add another attendee</string>
<!-- Export / Import --> <!-- Export / Import -->
<string name="import_events">Uvezi događaje</string> <string name="import_events">Uvezi događaje</string>
<string name="export_events">Izvezi događaje</string> <string name="export_events">Izvezi događaje</string>

View File

@@ -10,6 +10,7 @@
<string name="simple_event_list">Egyszerű bejegyzéslista</string> <string name="simple_event_list">Egyszerű bejegyzéslista</string>
<string name="no_upcoming_events">Seems like you don\'t have any upcoming events.</string> <string name="no_upcoming_events">Seems like you don\'t have any upcoming events.</string>
<string name="go_to_today">Go to today</string> <string name="go_to_today">Go to today</string>
<string name="go_to_date">Go to date</string>
<!-- Widget titles --> <!-- Widget titles -->
<string name="widget_monthly">Havi naptár</string> <string name="widget_monthly">Havi naptár</string>
@@ -97,6 +98,9 @@
<string name="add_another_reminder">Add another reminder</string> <string name="add_another_reminder">Add another reminder</string>
<string name="event_reminders">Event reminders</string> <string name="event_reminders">Event reminders</string>
<!-- Event attendees -->
<string name="add_another_attendee">Add another attendee</string>
<!-- Export / Import --> <!-- Export / Import -->
<string name="import_events">Import events</string> <string name="import_events">Import events</string>
<string name="export_events">Export events</string> <string name="export_events">Export events</string>

View File

@@ -10,6 +10,7 @@
<string name="simple_event_list">Lista semplice deli eventi</string> <string name="simple_event_list">Lista semplice deli eventi</string>
<string name="no_upcoming_events">Non c\'è nessun evento imminente.</string> <string name="no_upcoming_events">Non c\'è nessun evento imminente.</string>
<string name="go_to_today">Vai a oggi</string> <string name="go_to_today">Vai a oggi</string>
<string name="go_to_date">Vai alla data</string>
<!-- Widget titles --> <!-- Widget titles -->
<string name="widget_monthly">Calendario mensile</string> <string name="widget_monthly">Calendario mensile</string>
@@ -97,6 +98,9 @@
<string name="add_another_reminder">Aggiungi un altro promemoria</string> <string name="add_another_reminder">Aggiungi un altro promemoria</string>
<string name="event_reminders">Promemoria eventi</string> <string name="event_reminders">Promemoria eventi</string>
<!-- Event attendees -->
<string name="add_another_attendee">Aggiungi un partecipante</string>
<!-- Export / Import --> <!-- Export / Import -->
<string name="import_events">Importa eventi</string> <string name="import_events">Importa eventi</string>
<string name="export_events">Esporta eventi</string> <string name="export_events">Esporta eventi</string>
@@ -170,12 +174,12 @@
<string name="default_reminder_3">Promemoria predefinito 3</string> <string name="default_reminder_3">Promemoria predefinito 3</string>
<string name="view_to_open_from_widget">Vista da aprire dalla lista degli eventi del widget</string> <string name="view_to_open_from_widget">Vista da aprire dalla lista degli eventi del widget</string>
<string name="last_view">Ultima vista</string> <string name="last_view">Ultima vista</string>
<string name="new_events">New events</string> <string name="new_events">Nuovi eventi</string>
<string name="default_start_time">Default start time</string> <string name="default_start_time">Tempo di inizio predefinito</string>
<string name="next_full_hour">Next full hour</string> <string name="next_full_hour">Prossima ora completa</string>
<string name="default_duration">Default duration</string> <string name="default_duration">Durata predefinita</string>
<string name="last_used_one">Last used one</string> <string name="last_used_one">L\'ultimo utilizzato</string>
<string name="other_time">Other time</string> <string name="other_time">Altro periodo</string>
<!-- CalDAV sync --> <!-- CalDAV sync -->
<string name="caldav">CalDAV</string> <string name="caldav">CalDAV</string>

View File

@@ -10,6 +10,7 @@
<string name="simple_event_list">רשימת אירועים פשוטה</string> <string name="simple_event_list">רשימת אירועים פשוטה</string>
<string name="no_upcoming_events">נראה שאין לך אירועים בזמן הקרוב.</string> <string name="no_upcoming_events">נראה שאין לך אירועים בזמן הקרוב.</string>
<string name="go_to_today">Go to today</string> <string name="go_to_today">Go to today</string>
<string name="go_to_date">Go to date</string>
<!-- Widget titles --> <!-- Widget titles -->
<string name="widget_monthly">לוח השנה חודשית</string> <string name="widget_monthly">לוח השנה חודשית</string>
@@ -98,6 +99,9 @@
<string name="add_another_reminder">Add another reminder</string> <string name="add_another_reminder">Add another reminder</string>
<string name="event_reminders">Event reminders</string> <string name="event_reminders">Event reminders</string>
<!-- Event attendees -->
<string name="add_another_attendee">Add another attendee</string>
<!-- Export / Import --> <!-- Export / Import -->
<string name="import_events">ייבוא אירועים</string> <string name="import_events">ייבוא אירועים</string>
<string name="export_events">Export events</string> <string name="export_events">Export events</string>

View File

@@ -10,6 +10,7 @@
<string name="simple_event_list">シンプル 予定 リスト</string> <string name="simple_event_list">シンプル 予定 リスト</string>
<string name="no_upcoming_events">今後の予定はありません。</string> <string name="no_upcoming_events">今後の予定はありません。</string>
<string name="go_to_today">今日へ移動</string> <string name="go_to_today">今日へ移動</string>
<string name="go_to_date">Go to date</string>
<!-- Widget titles --> <!-- Widget titles -->
<string name="widget_monthly">カレンダー月</string> <string name="widget_monthly">カレンダー月</string>
@@ -97,6 +98,9 @@
<string name="add_another_reminder">Add another reminder</string> <string name="add_another_reminder">Add another reminder</string>
<string name="event_reminders">予定のリマインダー</string> <string name="event_reminders">予定のリマインダー</string>
<!-- Event attendees -->
<string name="add_another_attendee">Add another attendee</string>
<!-- Export / Import --> <!-- Export / Import -->
<string name="import_events">予定をインポート</string> <string name="import_events">予定をインポート</string>
<string name="export_events">予定をエクスポート</string> <string name="export_events">予定をエクスポート</string>

View File

@@ -10,6 +10,7 @@
<string name="simple_event_list">간단한 이벤트 목록</string> <string name="simple_event_list">간단한 이벤트 목록</string>
<string name="no_upcoming_events">다가올 이벤트가 없는 것 같습니다.</string> <string name="no_upcoming_events">다가올 이벤트가 없는 것 같습니다.</string>
<string name="go_to_today">오늘로 이동</string> <string name="go_to_today">오늘로 이동</string>
<string name="go_to_date">Go to date</string>
<!-- Widget titles --> <!-- Widget titles -->
<string name="widget_monthly">월별 달력</string> <string name="widget_monthly">월별 달력</string>
@@ -97,6 +98,9 @@
<string name="add_another_reminder">다른 알림 추가</string> <string name="add_another_reminder">다른 알림 추가</string>
<string name="event_reminders">Event reminders</string> <string name="event_reminders">Event reminders</string>
<!-- Event attendees -->
<string name="add_another_attendee">Add another attendee</string>
<!-- Export / Import --> <!-- Export / Import -->
<string name="import_events">이벤트들 가져 오기</string> <string name="import_events">이벤트들 가져 오기</string>
<string name="export_events">이벤트들 내보내기</string> <string name="export_events">이벤트들 내보내기</string>

View File

@@ -10,6 +10,7 @@
<string name="simple_event_list">Paprastas įvykių sąrašas</string> <string name="simple_event_list">Paprastas įvykių sąrašas</string>
<string name="no_upcoming_events">Atrodo jog Jūs neturite jokių įvyksiančių įvykių.</string> <string name="no_upcoming_events">Atrodo jog Jūs neturite jokių įvyksiančių įvykių.</string>
<string name="go_to_today">Eiti į šiandieną</string> <string name="go_to_today">Eiti į šiandieną</string>
<string name="go_to_date">Go to date</string>
<!-- Widget titles --> <!-- Widget titles -->
<string name="widget_monthly">Mėnesio kalendorius</string> <string name="widget_monthly">Mėnesio kalendorius</string>
@@ -97,6 +98,9 @@
<string name="add_another_reminder">Pridėti kitą priminimą</string> <string name="add_another_reminder">Pridėti kitą priminimą</string>
<string name="event_reminders">Įvykių priminimai</string> <string name="event_reminders">Įvykių priminimai</string>
<!-- Event attendees -->
<string name="add_another_attendee">Add another attendee</string>
<!-- Export / Import --> <!-- Export / Import -->
<string name="import_events">Importuoti įvykius</string> <string name="import_events">Importuoti įvykius</string>
<string name="export_events">Eksportuoti įvykius</string> <string name="export_events">Eksportuoti įvykius</string>

View File

@@ -10,6 +10,7 @@
<string name="simple_event_list">Enkel hendelsesliste</string> <string name="simple_event_list">Enkel hendelsesliste</string>
<string name="no_upcoming_events">Ser ut som du ikke har noen kommende hendelser.</string> <string name="no_upcoming_events">Ser ut som du ikke har noen kommende hendelser.</string>
<string name="go_to_today">Gå til idag</string> <string name="go_to_today">Gå til idag</string>
<string name="go_to_date">Go to date</string>
<!-- Widget titles --> <!-- Widget titles -->
<string name="widget_monthly">Månedskalender</string> <string name="widget_monthly">Månedskalender</string>
@@ -97,6 +98,9 @@
<string name="add_another_reminder">Legg til en annen påminnelse</string> <string name="add_another_reminder">Legg til en annen påminnelse</string>
<string name="event_reminders">Hendelsespåminnelser</string> <string name="event_reminders">Hendelsespåminnelser</string>
<!-- Event attendees -->
<string name="add_another_attendee">Add another attendee</string>
<!-- Export / Import --> <!-- Export / Import -->
<string name="import_events">Importer hendelser</string> <string name="import_events">Importer hendelser</string>
<string name="export_events">Eksporter hendelser</string> <string name="export_events">Eksporter hendelser</string>

View File

@@ -10,6 +10,7 @@
<string name="simple_event_list">Lijst</string> <string name="simple_event_list">Lijst</string>
<string name="no_upcoming_events">Niets gepland.</string> <string name="no_upcoming_events">Niets gepland.</string>
<string name="go_to_today">Naar vandaag</string> <string name="go_to_today">Naar vandaag</string>
<string name="go_to_date">Naar datum</string>
<!-- Widget titles --> <!-- Widget titles -->
<string name="widget_monthly">Maandweergave</string> <string name="widget_monthly">Maandweergave</string>
@@ -97,6 +98,9 @@
<string name="add_another_reminder">Herinnering toevoegen</string> <string name="add_another_reminder">Herinnering toevoegen</string>
<string name="event_reminders">Herinneringen</string> <string name="event_reminders">Herinneringen</string>
<!-- Event attendees -->
<string name="add_another_attendee">Persoon uitnodigen</string>
<!-- Export / Import --> <!-- Export / Import -->
<string name="import_events">Afspraken importeren</string> <string name="import_events">Afspraken importeren</string>
<string name="export_events">Afspraken exporteren</string> <string name="export_events">Afspraken exporteren</string>

View File

@@ -10,6 +10,7 @@
<string name="simple_event_list">Enkel hendelsesliste</string> <string name="simple_event_list">Enkel hendelsesliste</string>
<string name="no_upcoming_events">Ser ut som du ikke har noen kommende hendelser.</string> <string name="no_upcoming_events">Ser ut som du ikke har noen kommende hendelser.</string>
<string name="go_to_today">Gå til idag</string> <string name="go_to_today">Gå til idag</string>
<string name="go_to_date">Go to date</string>
<!-- Widget titles --> <!-- Widget titles -->
<string name="widget_monthly">Månedskalender</string> <string name="widget_monthly">Månedskalender</string>
@@ -97,6 +98,9 @@
<string name="add_another_reminder">Legg til en annen påminnelse</string> <string name="add_another_reminder">Legg til en annen påminnelse</string>
<string name="event_reminders">Event reminders</string> <string name="event_reminders">Event reminders</string>
<!-- Event attendees -->
<string name="add_another_attendee">Add another attendee</string>
<!-- Export / Import --> <!-- Export / Import -->
<string name="import_events">Importer hendelser</string> <string name="import_events">Importer hendelser</string>
<string name="export_events">Eksporter hendelser</string> <string name="export_events">Eksporter hendelser</string>

View File

@@ -10,6 +10,7 @@
<string name="simple_event_list">Prosta lista wydarzeń</string> <string name="simple_event_list">Prosta lista wydarzeń</string>
<string name="no_upcoming_events">Wygląda na to, że nie masz żadnych nadchodzących wydarzeń.</string> <string name="no_upcoming_events">Wygląda na to, że nie masz żadnych nadchodzących wydarzeń.</string>
<string name="go_to_today">Przejdź do dnia dzisiejszego</string> <string name="go_to_today">Przejdź do dnia dzisiejszego</string>
<string name="go_to_date">Go to date</string>
<!-- Widget titles --> <!-- Widget titles -->
<string name="widget_monthly">Prosty kalendarz - widok miesięczny</string> <string name="widget_monthly">Prosty kalendarz - widok miesięczny</string>
@@ -97,6 +98,9 @@
<string name="add_another_reminder">Dodaj inne przypomnienie</string> <string name="add_another_reminder">Dodaj inne przypomnienie</string>
   <string name="event_reminders">Przypomnienia</string>    <string name="event_reminders">Przypomnienia</string>
<!-- Event attendees -->
<string name="add_another_attendee">Add another attendee</string>
<!-- Export / Import --> <!-- Export / Import -->
<string name="import_events">Importuj wydarzenia</string> <string name="import_events">Importuj wydarzenia</string>
<string name="export_events">Eksportuj wydarzenia</string> <string name="export_events">Eksportuj wydarzenia</string>

View File

@@ -10,6 +10,7 @@
<string name="simple_event_list">Lista de eventos</string> <string name="simple_event_list">Lista de eventos</string>
<string name="no_upcoming_events">Parece que você não tem próximos eventos.</string> <string name="no_upcoming_events">Parece que você não tem próximos eventos.</string>
<string name="go_to_today">Ir para hoje</string> <string name="go_to_today">Ir para hoje</string>
<string name="go_to_date">Go to date</string>
<!-- Widget titles --> <!-- Widget titles -->
<string name="widget_monthly">Calendário mensal</string> <string name="widget_monthly">Calendário mensal</string>
@@ -97,6 +98,9 @@
<string name="add_another_reminder">Adicionar outro lembrete</string> <string name="add_another_reminder">Adicionar outro lembrete</string>
<string name="event_reminders">Lembretes de eventos</string> <string name="event_reminders">Lembretes de eventos</string>
<!-- Event attendees -->
<string name="add_another_attendee">Add another attendee</string>
<!-- Export / Import --> <!-- Export / Import -->
<string name="import_events">Importar eventos</string> <string name="import_events">Importar eventos</string>
<string name="export_events">Exportar eventos</string> <string name="export_events">Exportar eventos</string>

View File

@@ -10,6 +10,7 @@
<string name="simple_event_list">Lista de eventos</string> <string name="simple_event_list">Lista de eventos</string>
<string name="no_upcoming_events">Parece que você não tem eventos para breve</string> <string name="no_upcoming_events">Parece que você não tem eventos para breve</string>
<string name="go_to_today">Ir para hoje</string> <string name="go_to_today">Ir para hoje</string>
<string name="go_to_date">Go to date</string>
<!-- Widget titles --> <!-- Widget titles -->
<string name="widget_monthly">Calendário mensal</string> <string name="widget_monthly">Calendário mensal</string>
@@ -97,6 +98,9 @@
<string name="add_another_reminder">Adicionar outro lembrete</string> <string name="add_another_reminder">Adicionar outro lembrete</string>
<string name="event_reminders">Lembretes para eventos</string> <string name="event_reminders">Lembretes para eventos</string>
<!-- Event attendees -->
<string name="add_another_attendee">Add another attendee</string>
<!-- Export / Import --> <!-- Export / Import -->
<string name="import_events">Importar eventos</string> <string name="import_events">Importar eventos</string>
<string name="export_events">Exportar eventos</string> <string name="export_events">Exportar eventos</string>

View File

@@ -10,6 +10,7 @@
<string name="simple_event_list">Список событий</string> <string name="simple_event_list">Список событий</string>
<string name="no_upcoming_events">Похоже, нет предстоящих событий.</string> <string name="no_upcoming_events">Похоже, нет предстоящих событий.</string>
<string name="go_to_today">Сегодня</string> <string name="go_to_today">Сегодня</string>
<string name="go_to_date">Go to date</string>
<!-- Widget titles --> <!-- Widget titles -->
<string name="widget_monthly">Календарь на месяц</string> <string name="widget_monthly">Календарь на месяц</string>
@@ -97,6 +98,9 @@
<string name="add_another_reminder">Добавить ещё одно напоминание</string> <string name="add_another_reminder">Добавить ещё одно напоминание</string>
<string name="event_reminders">Напоминания о событиях</string> <string name="event_reminders">Напоминания о событиях</string>
<!-- Event attendees -->
<string name="add_another_attendee">Add another attendee</string>
<!-- Export / Import --> <!-- Export / Import -->
<string name="import_events">Импорт событий</string> <string name="import_events">Импорт событий</string>
<string name="export_events">Экспорт событий</string> <string name="export_events">Экспорт событий</string>

View File

@@ -10,6 +10,7 @@
<string name="simple_event_list">Jednoduchý zoznam</string> <string name="simple_event_list">Jednoduchý zoznam</string>
<string name="no_upcoming_events">Nemáte žiadne naplánované udalosti.</string> <string name="no_upcoming_events">Nemáte žiadne naplánované udalosti.</string>
<string name="go_to_today">Prejsť na dnešok</string> <string name="go_to_today">Prejsť na dnešok</string>
<string name="go_to_date">Prejsť na dátum</string>
<!-- Widget titles --> <!-- Widget titles -->
<string name="widget_monthly">Kalendár mesačný</string> <string name="widget_monthly">Kalendár mesačný</string>
@@ -97,6 +98,9 @@
<string name="add_another_reminder">Pridať ďalšiu pripomienku</string> <string name="add_another_reminder">Pridať ďalšiu pripomienku</string>
<string name="event_reminders">Pripomienky udalostí</string> <string name="event_reminders">Pripomienky udalostí</string>
<!-- Event attendees -->
<string name="add_another_attendee">Pridať ďalšieho účastníka</string>
<!-- Export / Import --> <!-- Export / Import -->
<string name="import_events">Importovať udalosti</string> <string name="import_events">Importovať udalosti</string>
<string name="export_events">Exportovať udalosti</string> <string name="export_events">Exportovať udalosti</string>
@@ -224,7 +228,7 @@
<!-- Strings displayed only on Google Playstore. Optional, but good to have --> <!-- Strings displayed only on Google Playstore. Optional, but good to have -->
<!-- Short description has to have less than 80 chars --> <!-- Short description has to have less than 80 chars -->
<string name="app_short_description">Jednoduchý kalendár s udalosťami, upraviteľným widgetom a bez reklám.</string> <string name="app_short_description">Offline kalendár pre vaše udalosti bez reklám, rešpektujúca vaše súkromie.</string>
<string name="app_long_description"> <string name="app_long_description">
Jednoduchý kalendár s možnosťou CalDAV synchronizácie. Viete si jednoducho vytvoriť opakujúce sa udalosti s pripomienkami, alebo zobraziť čísla týždňov. Jednoduchý kalendár s možnosťou CalDAV synchronizácie. Viete si jednoducho vytvoriť opakujúce sa udalosti s pripomienkami, alebo zobraziť čísla týždňov.

View File

@@ -10,6 +10,7 @@
<string name="simple_event_list">Händelselista</string> <string name="simple_event_list">Händelselista</string>
<string name="no_upcoming_events">Det verkar som att du inte har några kommande händelser.</string> <string name="no_upcoming_events">Det verkar som att du inte har några kommande händelser.</string>
<string name="go_to_today">Gå till idag</string> <string name="go_to_today">Gå till idag</string>
<string name="go_to_date">Gå till datum</string>
<!-- Widget titles --> <!-- Widget titles -->
<string name="widget_monthly">Kalender månadsvis</string> <string name="widget_monthly">Kalender månadsvis</string>
@@ -97,6 +98,9 @@
<string name="add_another_reminder">Lägg till en annan påminnelse</string> <string name="add_another_reminder">Lägg till en annan påminnelse</string>
<string name="event_reminders">Händelsepåminnelser</string> <string name="event_reminders">Händelsepåminnelser</string>
<!-- Event attendees -->
<string name="add_another_attendee">Add another attendee</string>
<!-- Export / Import --> <!-- Export / Import -->
<string name="import_events">Importera händelser</string> <string name="import_events">Importera händelser</string>
<string name="export_events">Exportera händelser</string> <string name="export_events">Exportera händelser</string>
@@ -136,13 +140,13 @@
<string name="national_holidays">Nationella helgdagar</string> <string name="national_holidays">Nationella helgdagar</string>
<string name="religious_holidays">Religiösa helgdagar</string> <string name="religious_holidays">Religiösa helgdagar</string>
<string name="holidays_imported_successfully">Helgdagarna har importerats till händelsetypen \"Helgdagar\"</string> <string name="holidays_imported_successfully">Helgdagarna har importerats till händelsetypen \"Helgdagar\"</string>
<string name="importing_some_holidays_failed">Vissa händelser kunde inte importeras</string> <string name="importing_some_holidays_failed">Importen av vissa händelser misslyckades</string>
<string name="importing_holidays_failed">Helgdagar kunde inte importeras</string> <string name="importing_holidays_failed">Importen av helgdagarna misslyckades</string>
<!-- Settings --> <!-- Settings -->
<string name="manage_event_types">Hantera händelsetyper</string> <string name="manage_event_types">Hantera händelsetyper</string>
<string name="start_day_at">Starta veckovydagen vid</string> <string name="start_day_at">Dagen börjar</string>
<string name="end_day_at">Sluta veckovydagen vid</string> <string name="end_day_at">Dagen slutar</string>
<string name="week_numbers">Visa veckonummer</string> <string name="week_numbers">Visa veckonummer</string>
<string name="vibrate">Vibrera vid påminnelseaviseringar</string> <string name="vibrate">Vibrera vid påminnelseaviseringar</string>
<string name="reminder_sound">Påminnelseljud</string> <string name="reminder_sound">Påminnelseljud</string>
@@ -170,12 +174,12 @@
<string name="default_reminder_3">Standardpåminnelse 3</string> <string name="default_reminder_3">Standardpåminnelse 3</string>
<string name="view_to_open_from_widget">Vy som öppnas från händelselistwidgeten</string> <string name="view_to_open_from_widget">Vy som öppnas från händelselistwidgeten</string>
<string name="last_view">Senaste vy</string> <string name="last_view">Senaste vy</string>
<string name="new_events">New events</string> <string name="new_events">Nya händelser</string>
<string name="default_start_time">Default start time</string> <string name="default_start_time">Standardstarttid</string>
<string name="next_full_hour">Next full hour</string> <string name="next_full_hour">Nästa heltimme</string>
<string name="default_duration">Default duration</string> <string name="default_duration">Standardvaraktighet</string>
<string name="last_used_one">Last used one</string> <string name="last_used_one">Senast använda</string>
<string name="other_time">Other time</string> <string name="other_time">Annan tid</string>
<!-- CalDAV sync --> <!-- CalDAV sync -->
<string name="caldav">CalDAV</string> <string name="caldav">CalDAV</string>

View File

@@ -10,6 +10,7 @@
<string name="simple_event_list">Basit etkinlik listesi</string> <string name="simple_event_list">Basit etkinlik listesi</string>
<string name="no_upcoming_events">Yaklaşan etkinlikleriniz yok gibi görünüyor.</string> <string name="no_upcoming_events">Yaklaşan etkinlikleriniz yok gibi görünüyor.</string>
<string name="go_to_today">Bugüne git</string> <string name="go_to_today">Bugüne git</string>
<string name="go_to_date">Go to date</string>
<!-- Widget titles --> <!-- Widget titles -->
<string name="widget_monthly">Aylık takvim</string> <string name="widget_monthly">Aylık takvim</string>
@@ -97,6 +98,9 @@
<string name="add_another_reminder">Başka hatırlatma ekle</string> <string name="add_another_reminder">Başka hatırlatma ekle</string>
<string name="event_reminders">Etkinlik hatırlatıcılar</string> <string name="event_reminders">Etkinlik hatırlatıcılar</string>
<!-- Event attendees -->
<string name="add_another_attendee">Add another attendee</string>
<!-- Export / Import --> <!-- Export / Import -->
<string name="import_events">Etkinlikleri içe aktar</string> <string name="import_events">Etkinlikleri içe aktar</string>
<string name="export_events">Etkinlikleri dışa aktar</string> <string name="export_events">Etkinlikleri dışa aktar</string>
@@ -170,12 +174,12 @@
<string name="default_reminder_3">Varsayılan hatırlatıcı 3</string> <string name="default_reminder_3">Varsayılan hatırlatıcı 3</string>
<string name="view_to_open_from_widget">Etkinlik listesi widget\'ından açılacak görünüm</string> <string name="view_to_open_from_widget">Etkinlik listesi widget\'ından açılacak görünüm</string>
<string name="last_view">Son görünüm</string> <string name="last_view">Son görünüm</string>
<string name="new_events">New events</string> <string name="new_events">Yeni etkinlikler</string>
<string name="default_start_time">Default start time</string> <string name="default_start_time">Varsayılan başlangıç zamanı</string>
<string name="next_full_hour">Next full hour</string> <string name="next_full_hour">Gelecek tam saat</string>
<string name="default_duration">Default duration</string> <string name="default_duration">Varsayılan süre</string>
<string name="last_used_one">Last used one</string> <string name="last_used_one">Son kullanılan</string>
<string name="other_time">Other time</string> <string name="other_time">Başka zaman</string>
<!-- CalDAV sync --> <!-- CalDAV sync -->
<string name="caldav">CalDAV</string> <string name="caldav">CalDAV</string>
@@ -189,7 +193,7 @@
<string name="syncing">Senkronize ediliyor…</string> <string name="syncing">Senkronize ediliyor…</string>
<string name="synchronization_completed">Senkronizasyon tamamlandı</string> <string name="synchronization_completed">Senkronizasyon tamamlandı</string>
<string name="select_a_different_caldav_color">Farklı bir renk seçin (yalnızca yerel olarak uygulanabilir)</string> <string name="select_a_different_caldav_color">Farklı bir renk seçin (yalnızca yerel olarak uygulanabilir)</string>
<string name="insufficient_permissions">You are not allowed to write in the selected calendar</string> <string name="insufficient_permissions">Seçili takvime yazmanıza izin verilmiyor</string>
<!-- alternative versions for some languages, use the same translations if you are not sure what this means --> <!-- alternative versions for some languages, use the same translations if you are not sure what this means -->
<!-- used in repetition, like "Every last Sunday" --> <!-- used in repetition, like "Every last Sunday" -->
@@ -223,7 +227,7 @@
<!-- Strings displayed only on Google Playstore. Optional, but good to have --> <!-- Strings displayed only on Google Playstore. Optional, but good to have -->
<!-- Short description has to have less than 80 chars --> <!-- Short description has to have less than 80 chars -->
<string name="app_short_description">An offline calendar for your events without ads, respecting your privacy.</string> <string name="app_short_description">Etkinlikleriniz için reklamsız, gizliliğinizi önemseyen bir çevrimdışı takvim.</string>
<string name="app_long_description"> <string name="app_long_description">
İsteğe bağlı CalDAV senkronizasyonu ile basit bir takvim. Kolayca tekrarlanan etkinlikler oluşturabilir ve hatırlatıcılar ayarlayabilir, ayrıca hafta sayılarını görüntüleyebilirsiniz. İsteğe bağlı CalDAV senkronizasyonu ile basit bir takvim. Kolayca tekrarlanan etkinlikler oluşturabilir ve hatırlatıcılar ayarlayabilir, ayrıca hafta sayılarını görüntüleyebilirsiniz.
@@ -235,7 +239,7 @@
Kişiler izni yalnızca doğum günlerini ve yıldönümlerini içe aktarırken kullanılır. Kişiler izni yalnızca doğum günlerini ve yıldönümlerini içe aktarırken kullanılır.
Bu uygulama, daha büyük bir uygulama serisinden sadece bir parça. Geri kalanı http://www.simplemobiletools.com adresinde bulabilirsiniz Bu uygulama, daha büyük bir uygulama serisinden sadece bir parça. Geri kalanı http://www.simplemobiletools.com adresinde bulabilirsiniz.
</string> </string>
<!-- <!--

View File

@@ -10,6 +10,7 @@
<string name="simple_event_list">簡易活動列表</string> <string name="simple_event_list">簡易活動列表</string>
<string name="no_upcoming_events">你近期似乎沒有任何活動。</string> <string name="no_upcoming_events">你近期似乎沒有任何活動。</string>
<string name="go_to_today">前往今天</string> <string name="go_to_today">前往今天</string>
<string name="go_to_date">Go to date</string>
<!-- Widget titles --> <!-- Widget titles -->
<string name="widget_monthly">月曆</string> <string name="widget_monthly">月曆</string>
@@ -97,6 +98,9 @@
<string name="add_another_reminder">新增另一個提醒</string> <string name="add_another_reminder">新增另一個提醒</string>
<string name="event_reminders">活動提醒</string> <string name="event_reminders">活動提醒</string>
<!-- Event attendees -->
<string name="add_another_attendee">Add another attendee</string>
<!-- Export / Import --> <!-- Export / Import -->
<string name="import_events">匯入活動</string> <string name="import_events">匯入活動</string>
<string name="export_events">匯出活動</string> <string name="export_events">匯出活動</string>
@@ -170,12 +174,12 @@
<string name="default_reminder_3">預設提醒3</string> <string name="default_reminder_3">預設提醒3</string>
<string name="view_to_open_from_widget">從活動列表小工具開啟的檢視畫面</string> <string name="view_to_open_from_widget">從活動列表小工具開啟的檢視畫面</string>
<string name="last_view">最後的檢視畫面</string> <string name="last_view">最後的檢視畫面</string>
<string name="new_events">New events</string> <string name="new_events">新活動</string>
<string name="default_start_time">Default start time</string> <string name="default_start_time">預設開始時間</string>
<string name="next_full_hour">Next full hour</string> <string name="next_full_hour">整整下個小時</string>
<string name="default_duration">Default duration</string> <string name="default_duration">預設持續時間</string>
<string name="last_used_one">Last used one</string> <string name="last_used_one">最後使用</string>
<string name="other_time">Other time</string> <string name="other_time">其他時間</string>
<!-- CalDAV sync --> <!-- CalDAV sync -->
<string name="caldav">CalDAV</string> <string name="caldav">CalDAV</string>

View File

@@ -28,4 +28,6 @@
<dimen name="event_color_bar_width">4dp</dimen> <dimen name="event_color_bar_width">4dp</dimen>
<dimen name="event_color_bar_height">100dp</dimen> <dimen name="event_color_bar_height">100dp</dimen>
<dimen name="avatar_size">40dp</dimen>
</resources> </resources>

View File

@@ -2,6 +2,10 @@
<resources> <resources>
<!-- Release notes --> <!-- Release notes -->
<string name="release_143">
Allow setting default start time/duration/event type for new events\n
Allow exporting/importing settings
</string>
<string name="release_129">Allow setting default event reminders, not always reuse the last events\' ones</string> <string name="release_129">Allow setting default event reminders, not always reuse the last events\' ones</string>
<string name="release_119"> <string name="release_119">
Allow changing the app launcher icon color\n Allow changing the app launcher icon color\n

View File

@@ -10,6 +10,7 @@
<string name="simple_event_list">Simple event list</string> <string name="simple_event_list">Simple event list</string>
<string name="no_upcoming_events">Seems like you don\'t have any upcoming events.</string> <string name="no_upcoming_events">Seems like you don\'t have any upcoming events.</string>
<string name="go_to_today">Go to today</string> <string name="go_to_today">Go to today</string>
<string name="go_to_date">Go to date</string>
<!-- Widget titles --> <!-- Widget titles -->
<string name="widget_monthly">Calendar monthly</string> <string name="widget_monthly">Calendar monthly</string>
@@ -97,6 +98,9 @@
<string name="add_another_reminder">Add another reminder</string> <string name="add_another_reminder">Add another reminder</string>
<string name="event_reminders">Event reminders</string> <string name="event_reminders">Event reminders</string>
<!-- Event attendees -->
<string name="add_another_attendee">Add another attendee</string>
<!-- Export / Import --> <!-- Export / Import -->
<string name="import_events">Import events</string> <string name="import_events">Import events</string>
<string name="export_events">Export events</string> <string name="export_events">Export events</string>
@@ -224,7 +228,7 @@
<!-- Strings displayed only on Google Playstore. Optional, but good to have --> <!-- Strings displayed only on Google Playstore. Optional, but good to have -->
<!-- Short description has to have less than 80 chars --> <!-- Short description has to have less than 80 chars -->
<string name="app_short_description">Offline kalendár pre vaše udalosti bez reklám, rešpektujúca vaše súkromie.</string> <string name="app_short_description">An offline calendar for your events without ads, respecting your privacy.</string>
<string name="app_long_description"> <string name="app_long_description">
A simple calendar with optional CalDAV synchronization. You can easily create recurring events and setup reminders, it can also display week numbers. A simple calendar with optional CalDAV synchronization. You can easily create recurring events and setup reminders, it can also display week numbers.

View File

@@ -6,11 +6,13 @@ buildscript {
repositories { repositories {
google() google()
jcenter() jcenter()
maven { url "https://plugins.gradle.org/m2" }
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:3.3.1' classpath 'com.android.tools.build:gradle:3.3.2'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "de.timfreiheit.resourceplaceholders:placeholders:0.3"
// NOTE: Do not place your application dependencies here; they belong // NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files // in the individual module build.gradle files

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 96 KiB

After

Width:  |  Height:  |  Size: 149 KiB