Merge pull request #8 from SimpleMobileTools/master

гзв
This commit is contained in:
solokot 2018-05-10 14:12:39 +03:00 committed by GitHub
commit 3d834329fb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
207 changed files with 1518 additions and 517 deletions

View File

@ -46,7 +46,7 @@ ext {
}
dependencies {
implementation 'com.simplemobiletools:commons:3.18.23'
implementation 'com.simplemobiletools:commons:4.0.1'
implementation 'joda-time:joda-time:2.9.9'
implementation 'com.facebook.stetho:stetho:1.5.0'
implementation 'com.android.support:multidex:1.0.3'

View File

@ -29,8 +29,6 @@
android:launchMode="singleTask"
android:theme="@style/SplashTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
@ -198,5 +196,252 @@
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths"/>
</provider>
<!-- Do not append ".Orange" to the default alias "name", it would remove the old homescreen launcher of users at upgrade -->
<activity-alias
android:name=".activities.SplashActivity"
android:enabled="true"
android:icon="@mipmap/ic_launcher"
android:roundIcon="@mipmap/ic_launcher"
android:targetActivity=".activities.SplashActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity-alias>
<activity-alias
android:name=".activities.SplashActivity.Red"
android:enabled="false"
android:icon="@mipmap/ic_launcher_red"
android:roundIcon="@mipmap/ic_launcher_red"
android:targetActivity=".activities.SplashActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity-alias>
<activity-alias
android:name=".activities.SplashActivity.Pink"
android:enabled="false"
android:icon="@mipmap/ic_launcher_pink"
android:roundIcon="@mipmap/ic_launcher_pink"
android:targetActivity=".activities.SplashActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity-alias>
<activity-alias
android:name=".activities.SplashActivity.Purple"
android:enabled="false"
android:icon="@mipmap/ic_launcher_purple"
android:roundIcon="@mipmap/ic_launcher_purple"
android:targetActivity=".activities.SplashActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity-alias>
<activity-alias
android:name=".activities.SplashActivity.Deep_purple"
android:enabled="false"
android:icon="@mipmap/ic_launcher_deep_purple"
android:roundIcon="@mipmap/ic_launcher_deep_purple"
android:targetActivity=".activities.SplashActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity-alias>
<activity-alias
android:name=".activities.SplashActivity.Indigo"
android:enabled="false"
android:icon="@mipmap/ic_launcher_indigo"
android:roundIcon="@mipmap/ic_launcher_indigo"
android:targetActivity=".activities.SplashActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity-alias>
<activity-alias
android:name=".activities.SplashActivity.Blue"
android:enabled="false"
android:icon="@mipmap/ic_launcher_blue"
android:roundIcon="@mipmap/ic_launcher_blue"
android:targetActivity=".activities.SplashActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity-alias>
<activity-alias
android:name=".activities.SplashActivity.Light_blue"
android:enabled="false"
android:icon="@mipmap/ic_launcher_light_blue"
android:roundIcon="@mipmap/ic_launcher_light_blue"
android:targetActivity=".activities.SplashActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity-alias>
<activity-alias
android:name=".activities.SplashActivity.Cyan"
android:enabled="false"
android:icon="@mipmap/ic_launcher_cyan"
android:roundIcon="@mipmap/ic_launcher_cyan"
android:targetActivity=".activities.SplashActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity-alias>
<activity-alias
android:name=".activities.SplashActivity.Teal"
android:enabled="false"
android:icon="@mipmap/ic_launcher_teal"
android:roundIcon="@mipmap/ic_launcher_teal"
android:targetActivity=".activities.SplashActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity-alias>
<activity-alias
android:name=".activities.SplashActivity.Green"
android:enabled="false"
android:icon="@mipmap/ic_launcher_green"
android:roundIcon="@mipmap/ic_launcher_green"
android:targetActivity=".activities.SplashActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity-alias>
<activity-alias
android:name=".activities.SplashActivity.Light_green"
android:enabled="false"
android:icon="@mipmap/ic_launcher_light_green"
android:roundIcon="@mipmap/ic_launcher_light_green"
android:targetActivity=".activities.SplashActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity-alias>
<activity-alias
android:name=".activities.SplashActivity.Lime"
android:enabled="false"
android:icon="@mipmap/ic_launcher_lime"
android:roundIcon="@mipmap/ic_launcher_lime"
android:targetActivity=".activities.SplashActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity-alias>
<activity-alias
android:name=".activities.SplashActivity.Yellow"
android:enabled="false"
android:icon="@mipmap/ic_launcher_yellow"
android:roundIcon="@mipmap/ic_launcher_yellow"
android:targetActivity=".activities.SplashActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity-alias>
<activity-alias
android:name=".activities.SplashActivity.Amber"
android:enabled="false"
android:icon="@mipmap/ic_launcher_amber"
android:roundIcon="@mipmap/ic_launcher_amber"
android:targetActivity=".activities.SplashActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity-alias>
<activity-alias
android:name=".activities.SplashActivity.Deep_orange"
android:enabled="false"
android:icon="@mipmap/ic_launcher_deep_orange"
android:roundIcon="@mipmap/ic_launcher_deep_orange"
android:targetActivity=".activities.SplashActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity-alias>
<activity-alias
android:name=".activities.SplashActivity.Brown"
android:enabled="false"
android:icon="@mipmap/ic_launcher_brown"
android:roundIcon="@mipmap/ic_launcher_brown"
android:targetActivity=".activities.SplashActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity-alias>
<activity-alias
android:name=".activities.SplashActivity.Blue_grey"
android:enabled="false"
android:icon="@mipmap/ic_launcher_blue_grey"
android:roundIcon="@mipmap/ic_launcher_blue_grey"
android:targetActivity=".activities.SplashActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity-alias>
<activity-alias
android:name=".activities.SplashActivity.Grey_black"
android:enabled="false"
android:icon="@mipmap/ic_launcher_grey_black"
android:roundIcon="@mipmap/ic_launcher_grey_black"
android:targetActivity=".activities.SplashActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity-alias>
</application>
</manifest>

View File

@ -60,10 +60,21 @@ class EventActivity : SimpleActivity() {
return
}
val localEventType = dbHelper.getEventType(config.lastUsedLocalEventTypeId)
if (localEventType == null || localEventType.caldavCalendarId != 0) {
config.lastUsedLocalEventTypeId = DBHelper.REGULAR_EVENT_TYPE_ID
}
mEventTypeId = config.lastUsedLocalEventTypeId
if (event != null) {
mEvent = event
mEventOccurrenceTS = intent.getIntExtra(EVENT_OCCURRENCE_TS, 0)
setupEditEvent()
if (intent.getBooleanExtra(IS_DUPLICATE_INTENT, false)) {
mEvent.id = 0
}
} else {
mEvent = Event()
mReminder1Minutes = config.defaultReminderMinutes
@ -109,6 +120,7 @@ class EventActivity : SimpleActivity() {
if (wasActivityInitialized) {
menu.findItem(R.id.delete).isVisible = mEvent.id != 0
menu.findItem(R.id.share).isVisible = mEvent.id != 0
menu.findItem(R.id.duplicate).isVisible = mEvent.id != 0
}
return true
}
@ -117,6 +129,7 @@ class EventActivity : SimpleActivity() {
when (item.itemId) {
R.id.save -> saveEvent()
R.id.delete -> deleteEvent()
R.id.duplicate -> duplicateEvent()
R.id.share -> shareEvent()
else -> return super.onOptionsItemSelected(item)
}
@ -149,8 +162,8 @@ class EventActivity : SimpleActivity() {
private fun setupNewEvent() {
window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE)
supportActionBar?.title = resources.getString(R.string.new_event)
val isLastCaldavCalendarOK = config.caldavSync && config.getSyncedCalendarIdsAsList().contains(config.lastUsedCaldavCalendar.toString())
mEventCalendarId = if (isLastCaldavCalendarOK) config.lastUsedCaldavCalendar else STORED_LOCALLY_ONLY
val isLastCaldavCalendarOK = config.caldavSync && config.getSyncedCalendarIdsAsList().contains(config.lastUsedCaldavCalendarId.toString())
mEventCalendarId = if (isLastCaldavCalendarOK) config.lastUsedCaldavCalendarId else STORED_LOCALLY_ONLY
if (intent.action == Intent.ACTION_EDIT || intent.action == Intent.ACTION_INSERT) {
val startTS = (intent.getLongExtra("beginTime", System.currentTimeMillis()) / 1000).toInt()
@ -208,7 +221,7 @@ class EventActivity : SimpleActivity() {
if (mRepeatInterval.isXWeeklyRepetition()) {
setRepeatRule(Math.pow(2.0, (mEventStartDateTime.dayOfWeek - 1).toDouble()).toInt())
} else if (mRepeatInterval.isXMonthlyRepetition()) {
setRepeatRule(REPEAT_MONTH_SAME_DAY)
setRepeatRule(REPEAT_SAME_DAY)
}
}
@ -216,7 +229,7 @@ class EventActivity : SimpleActivity() {
event_repetition_limit_holder.beGoneIf(limit == 0)
checkRepetitionLimitText()
event_repetition_rule_holder.beVisibleIf(mRepeatInterval.isXWeeklyRepetition() || mRepeatInterval.isXMonthlyRepetition())
event_repetition_rule_holder.beVisibleIf(mRepeatInterval.isXWeeklyRepetition() || mRepeatInterval.isXMonthlyRepetition() || mRepeatInterval.isXYearlyRepetition())
checkRepetitionRuleText()
}
@ -252,36 +265,52 @@ class EventActivity : SimpleActivity() {
private fun showRepetitionRuleDialog() {
hideKeyboard()
if (mRepeatInterval.isXWeeklyRepetition()) {
RepeatRuleWeeklyDialog(this, mRepeatRule) {
when {
mRepeatInterval.isXWeeklyRepetition() -> RepeatRuleWeeklyDialog(this, mRepeatRule) {
setRepeatRule(it)
}
} else if (mRepeatInterval.isXMonthlyRepetition()) {
val items = arrayListOf(RadioItem(REPEAT_MONTH_SAME_DAY, getString(R.string.repeat_on_the_same_day)))
// split Every Last Sunday and Every Fourth Sunday of the month, if the month has 4 sundays
if (isLastWeekDayOfMonth()) {
val order = (mEventStartDateTime.dayOfMonth - 1) / 7 + 1
if (order == 4) {
items.add(RadioItem(REPEAT_MONTH_ORDER_WEEKDAY, getRepeatXthDayString(true, REPEAT_MONTH_ORDER_WEEKDAY)))
items.add(RadioItem(REPEAT_MONTH_ORDER_WEEKDAY_USE_LAST, getRepeatXthDayString(true, REPEAT_MONTH_ORDER_WEEKDAY_USE_LAST)))
} else if (order == 5) {
items.add(RadioItem(REPEAT_MONTH_ORDER_WEEKDAY_USE_LAST, getRepeatXthDayString(true, REPEAT_MONTH_ORDER_WEEKDAY_USE_LAST)))
mRepeatInterval.isXMonthlyRepetition() -> {
val items = getAvailableMonthlyRepetitionRules()
RadioGroupDialog(this, items, mRepeatRule) {
setRepeatRule(it as Int)
}
} else {
items.add(RadioItem(REPEAT_MONTH_ORDER_WEEKDAY, getRepeatXthDayString(true, REPEAT_MONTH_ORDER_WEEKDAY)))
}
if (isLastDayOfTheMonth()) {
items.add(RadioItem(REPEAT_MONTH_LAST_DAY, getString(R.string.repeat_on_the_last_day)))
}
RadioGroupDialog(this, items, mRepeatRule) {
setRepeatRule(it as Int)
mRepeatInterval.isXYearlyRepetition() -> {
val items = getAvailableYearlyRepetitionRules()
RadioGroupDialog(this, items, mRepeatRule) {
setRepeatRule(it as Int)
}
}
}
}
private fun getAvailableMonthlyRepetitionRules(): ArrayList<RadioItem> {
val items = arrayListOf(RadioItem(REPEAT_SAME_DAY, getString(R.string.repeat_on_the_same_day_monthly)))
// split Every Last Sunday and Every Fourth Sunday of the month, if the month has 4 sundays
if (isLastWeekDayOfMonth()) {
val order = (mEventStartDateTime.dayOfMonth - 1) / 7 + 1
if (order == 4) {
items.add(RadioItem(REPEAT_ORDER_WEEKDAY, getRepeatXthDayString(true, REPEAT_ORDER_WEEKDAY)))
items.add(RadioItem(REPEAT_ORDER_WEEKDAY_USE_LAST, getRepeatXthDayString(true, REPEAT_ORDER_WEEKDAY_USE_LAST)))
} else if (order == 5) {
items.add(RadioItem(REPEAT_ORDER_WEEKDAY_USE_LAST, getRepeatXthDayString(true, REPEAT_ORDER_WEEKDAY_USE_LAST)))
}
} else {
items.add(RadioItem(REPEAT_ORDER_WEEKDAY, getRepeatXthDayString(true, REPEAT_ORDER_WEEKDAY)))
}
if (isLastDayOfTheMonth()) {
items.add(RadioItem(REPEAT_LAST_DAY, getString(R.string.repeat_on_the_last_day_monthly)))
}
return items
}
private fun getAvailableYearlyRepetitionRules(): ArrayList<RadioItem> {
val items = arrayListOf(RadioItem(REPEAT_SAME_DAY, getString(R.string.repeat_on_the_same_day_monthly)))
return items
}
private fun isLastDayOfTheMonth() = mEventStartDateTime.dayOfMonth == mEventStartDateTime.dayOfMonth().withMaximumValue().dayOfMonth
private fun isLastWeekDayOfMonth() = mEventStartDateTime.monthOfYear != mEventStartDateTime.plusDays(7).monthOfYear
@ -312,7 +341,7 @@ class EventActivity : SimpleActivity() {
private fun getOrderString(repeatRule: Int): String {
val dayOfMonth = mEventStartDateTime.dayOfMonth
var order = (dayOfMonth - 1) / 7 + 1
if (order == 4 && isLastWeekDayOfMonth() && repeatRule == REPEAT_MONTH_ORDER_WEEKDAY_USE_LAST) {
if (order == 4 && isLastWeekDayOfMonth() && repeatRule == REPEAT_ORDER_WEEKDAY_USE_LAST) {
order = -1
}
@ -347,23 +376,38 @@ class EventActivity : SimpleActivity() {
}
private fun checkRepetitionRuleText() {
if (mRepeatInterval.isXWeeklyRepetition()) {
event_repetition_rule.text = if (mRepeatRule == EVERY_DAY_BIT) getString(R.string.every_day) else getSelectedDaysString(mRepeatRule)
} else if (mRepeatInterval.isXMonthlyRepetition()) {
val repeatString = if (mRepeatRule == REPEAT_MONTH_ORDER_WEEKDAY_USE_LAST || mRepeatRule == REPEAT_MONTH_ORDER_WEEKDAY)
R.string.repeat else R.string.repeat_on
when {
mRepeatInterval.isXWeeklyRepetition() -> {
event_repetition_rule.text = if (mRepeatRule == EVERY_DAY_BIT) getString(R.string.every_day) else getSelectedDaysString(mRepeatRule)
}
mRepeatInterval.isXMonthlyRepetition() -> {
val repeatString = if (mRepeatRule == REPEAT_ORDER_WEEKDAY_USE_LAST || mRepeatRule == REPEAT_ORDER_WEEKDAY)
R.string.repeat else R.string.repeat_on
event_repetition_rule_label.text = getString(repeatString)
event_repetition_rule.text = getMonthlyRepetitionRuleText()
event_repetition_rule_label.text = getString(repeatString)
event_repetition_rule.text = getMonthlyRepetitionRuleText()
}
mRepeatInterval.isXYearlyRepetition() -> {
val repeatString = if (mRepeatRule == REPEAT_ORDER_WEEKDAY_USE_LAST || mRepeatRule == REPEAT_ORDER_WEEKDAY)
R.string.repeat else R.string.repeat_on
event_repetition_rule_label.text = getString(repeatString)
event_repetition_rule.text = getYearlyRepetitionRuleText()
}
}
}
private fun getMonthlyRepetitionRuleText() = when (mRepeatRule) {
REPEAT_MONTH_SAME_DAY -> getString(R.string.the_same_day)
REPEAT_MONTH_LAST_DAY -> getString(R.string.the_last_day)
REPEAT_SAME_DAY -> getString(R.string.the_same_day)
REPEAT_LAST_DAY -> getString(R.string.the_last_day)
else -> getRepeatXthDayString(false, mRepeatRule)
}
private fun getYearlyRepetitionRuleText() = when (mRepeatRule) {
REPEAT_SAME_DAY -> getString(R.string.the_same_day)
else -> ""
}
private fun showEventTypeDialog() {
hideKeyboard()
SelectEventTypeDialog(this, mEventTypeId, false) {
@ -421,7 +465,7 @@ class EventActivity : SimpleActivity() {
val eventType = dbHelper.getEventType(mEventTypeId)
if (eventType != null) {
event_type.text = eventType.title
event_type_color.setBackgroundWithStroke(eventType.color, config.backgroundColor)
event_type_color.setFillWithStroke(eventType.color, config.backgroundColor)
}
}
@ -440,11 +484,11 @@ class EventActivity : SimpleActivity() {
hideKeyboard()
SelectEventCalendarDialog(this, calendars, mEventCalendarId) {
if (mEventCalendarId != STORED_LOCALLY_ONLY && it == STORED_LOCALLY_ONLY) {
mEventTypeId = DBHelper.REGULAR_EVENT_TYPE_ID
mEventTypeId = config.lastUsedLocalEventTypeId
updateEventType()
}
mEventCalendarId = it
config.lastUsedCaldavCalendar = it
config.lastUsedCaldavCalendarId = it
updateCurrentCalendarInfo(getCalendarWithId(calendars, it))
}
}
@ -453,7 +497,7 @@ class EventActivity : SimpleActivity() {
}
}
private fun getCalendarId() = if (mEvent.source == SOURCE_SIMPLE_CALENDAR) config.lastUsedCaldavCalendar else mEvent.getCalDAVCalendarId()
private fun getCalendarId() = if (mEvent.source == SOURCE_SIMPLE_CALENDAR) config.lastUsedCaldavCalendarId else mEvent.getCalDAVCalendarId()
private fun getCalendarWithId(calendars: List<CalDAVCalendar>, calendarId: Int): CalDAVCalendar? =
calendars.firstOrNull { it.id == calendarId }
@ -465,9 +509,14 @@ class EventActivity : SimpleActivity() {
event_caldav_calendar_email.beGoneIf(currentCalendar == null)
if (currentCalendar == null) {
val mediumMargin = resources.getDimension(R.dimen.medium_margin).toInt()
event_caldav_calendar_name.apply {
text = getString(R.string.store_locally_only)
setPadding(paddingLeft, paddingTop, paddingRight, resources.getDimension(R.dimen.medium_margin).toInt())
setPadding(paddingLeft, paddingTop, paddingRight, mediumMargin)
}
event_caldav_calendar_holder.apply {
setPadding(paddingLeft, mediumMargin, paddingRight, mediumMargin)
}
} else {
event_caldav_calendar_email.text = currentCalendar.accountName
@ -475,6 +524,10 @@ class EventActivity : SimpleActivity() {
text = currentCalendar.displayName
setPadding(paddingLeft, paddingTop, paddingRight, resources.getDimension(R.dimen.tiny_margin).toInt())
}
event_caldav_calendar_holder.apply {
setPadding(paddingLeft, 0, paddingRight, 0)
}
}
}
@ -499,6 +552,16 @@ class EventActivity : SimpleActivity() {
}
}
private fun duplicateEvent() {
Intent(this, EventActivity::class.java).apply {
putExtra(EVENT_ID, mEvent.id)
putExtra(EVENT_OCCURRENCE_TS, mEventOccurrenceTS)
putExtra(IS_DUPLICATE_INTENT, true)
startActivity(this)
}
finish()
}
private fun saveEvent() {
val newTitle = event_title.value
if (newTitle.isEmpty()) {
@ -519,16 +582,17 @@ class EventActivity : SimpleActivity() {
val oldSource = mEvent.source
val newImportId = if (mEvent.id != 0) mEvent.importId else UUID.randomUUID().toString().replace("-", "") + System.currentTimeMillis().toString()
val newEventType = if (!config.caldavSync || config.lastUsedCaldavCalendar == 0 || mEventCalendarId == STORED_LOCALLY_ONLY) {
val newEventType = if (!config.caldavSync || config.lastUsedCaldavCalendarId == 0 || mEventCalendarId == STORED_LOCALLY_ONLY) {
mEventTypeId
} else {
dbHelper.getEventTypeWithCalDAVCalendarId(config.lastUsedCaldavCalendar)?.id ?: DBHelper.REGULAR_EVENT_TYPE_ID
dbHelper.getEventTypeWithCalDAVCalendarId(config.lastUsedCaldavCalendarId)?.id ?: config.lastUsedLocalEventTypeId
}
val newSource = if (!config.caldavSync || config.lastUsedCaldavCalendar == 0 || mEventCalendarId == STORED_LOCALLY_ONLY) {
val newSource = if (!config.caldavSync || config.lastUsedCaldavCalendarId == 0 || mEventCalendarId == STORED_LOCALLY_ONLY) {
config.lastUsedLocalEventTypeId = newEventType
SOURCE_SIMPLE_CALENDAR
} else {
"$CALDAV-${config.lastUsedCaldavCalendar}"
"$CALDAV-${config.lastUsedCaldavCalendarId}"
}
val reminders = sortedSetOf(mReminder1Minutes, mReminder2Minutes, mReminder3Minutes).filter { it != REMINDER_OFF }
@ -771,8 +835,8 @@ class EventActivity : SimpleActivity() {
setRepeatRule(Math.pow(2.0, (mEventStartDateTime.dayOfWeek - 1).toDouble()).toInt())
}
} else if (mRepeatInterval.isXMonthlyRepetition()) {
if (mRepeatRule == REPEAT_MONTH_LAST_DAY && !isLastDayOfTheMonth())
mRepeatRule = REPEAT_MONTH_SAME_DAY
if (mRepeatRule == REPEAT_LAST_DAY && !isLastDayOfTheMonth())
mRepeatRule = REPEAT_SAME_DAY
checkRepetitionRuleText()
}
}

View File

@ -63,11 +63,12 @@ class MainActivity : SimpleActivity(), RefreshRecyclerViewListener {
private var mStoredDayCode = ""
private var mStoredIsSundayFirst = false
private var mStoredUse24HourFormat = false
private var mStoredDimPastEvents = true
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
appLaunched()
appLaunched(BuildConfig.APPLICATION_ID)
// just get a reference to the database to make sure it is created properly
dbHelper
@ -83,32 +84,8 @@ class MainActivity : SimpleActivity(), RefreshRecyclerViewListener {
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
}
if (intent?.action == Intent.ACTION_VIEW && intent.data != null) {
val uri = intent.data
if (uri.authority == "com.android.calendar") {
if (uri.path.startsWith("/events")) {
// intents like content://com.android.calendar/events/1756
val eventId = uri.lastPathSegment
val id = dbHelper.getEventIdWithLastImportId(eventId)
if (id != 0) {
Intent(this, EventActivity::class.java).apply {
putExtra(EVENT_ID, id)
startActivity(this)
}
} else {
toast(R.string.unknown_error_occurred)
}
} else if (intent?.extras?.getBoolean("DETAIL_VIEW", false) == true) {
// clicking date on a third party widget: content://com.android.calendar/time/1507309245683
val timestamp = uri.pathSegments.last()
if (timestamp.areDigitsOnly()) {
openDayAt(timestamp.toLong())
return
}
}
} else {
tryImportEventsFromFile(uri)
}
if (!checkViewIntents()) {
return
}
if (!checkOpenIntents()) {
@ -127,7 +104,7 @@ class MainActivity : SimpleActivity(), RefreshRecyclerViewListener {
override fun onResume() {
super.onResume()
if (mStoredTextColor != config.textColor || mStoredBackgroundColor != config.backgroundColor || mStoredPrimaryColor != config.primaryColor
|| mStoredDayCode != Formatter.getTodayCode(applicationContext)) {
|| mStoredDayCode != Formatter.getTodayCode(applicationContext) || mStoredDimPastEvents != config.dimPastEvents) {
updateViewPager()
}
@ -146,6 +123,8 @@ class MainActivity : SimpleActivity(), RefreshRecyclerViewListener {
if (config.storedView != EVENTS_LIST_VIEW) {
updateTextColors(calendar_coordinator)
}
search_placeholder.setTextColor(config.textColor)
search_placeholder_2.setTextColor(config.textColor)
calendar_fab.setColors(config.textColor, getAdjustedPrimaryColor(), config.backgroundColor)
search_holder.background = ColorDrawable(config.backgroundColor)
}
@ -213,6 +192,7 @@ class MainActivity : SimpleActivity(), RefreshRecyclerViewListener {
super.onNewIntent(intent)
setIntent(intent)
checkOpenIntents()
checkViewIntents()
}
private fun storeStateVariables() {
@ -222,6 +202,7 @@ class MainActivity : SimpleActivity(), RefreshRecyclerViewListener {
mStoredPrimaryColor = primaryColor
mStoredBackgroundColor = backgroundColor
mStoredUse24HourFormat = use24HourFormat
mStoredDimPastEvents = dimPastEvents
}
mStoredDayCode = Formatter.getTodayCode(applicationContext)
}
@ -293,6 +274,37 @@ class MainActivity : SimpleActivity(), RefreshRecyclerViewListener {
return false
}
private fun checkViewIntents(): Boolean {
if (intent?.action == Intent.ACTION_VIEW && intent.data != null) {
val uri = intent.data
if (uri.authority == "com.android.calendar") {
if (uri.path.startsWith("/events")) {
// intents like content://com.android.calendar/events/1756
val eventId = uri.lastPathSegment
val id = dbHelper.getEventIdWithLastImportId(eventId)
if (id != 0) {
Intent(this, EventActivity::class.java).apply {
putExtra(EVENT_ID, id)
startActivity(this)
}
} else {
toast(R.string.unknown_error_occurred)
}
} else if (intent?.extras?.getBoolean("DETAIL_VIEW", false) == true) {
// clicking date on a third party widget: content://com.android.calendar/time/1507309245683
val timestamp = uri.pathSegments.last()
if (timestamp.areDigitsOnly()) {
openDayAt(timestamp.toLong())
return false
}
}
} else {
tryImportEventsFromFile(uri)
}
}
return true
}
private fun showViewDialog() {
val items = arrayListOf(
RadioItem(DAILY_VIEW, getString(R.string.daily_view)),
@ -372,7 +384,7 @@ class MainActivity : SimpleActivity(), RefreshRecyclerViewListener {
eventTypeId = dbHelper.insertEventType(eventType)
}
val result = IcsImporter(this).importEvents(it as String, eventTypeId, 0)
val result = IcsImporter(this).importEvents(it as String, eventTypeId, 0, false)
handleParseResult(result)
if (result != IcsImporter.ImportResult.IMPORT_FAIL) {
runOnUiThread {

View File

@ -8,10 +8,7 @@ import android.text.TextUtils
import com.simplemobiletools.calendar.R
import com.simplemobiletools.calendar.dialogs.SelectCalendarsDialog
import com.simplemobiletools.calendar.extensions.*
import com.simplemobiletools.calendar.helpers.CalDAVHandler
import com.simplemobiletools.calendar.helpers.FONT_SIZE_LARGE
import com.simplemobiletools.calendar.helpers.FONT_SIZE_MEDIUM
import com.simplemobiletools.calendar.helpers.FONT_SIZE_SMALL
import com.simplemobiletools.calendar.helpers.*
import com.simplemobiletools.calendar.models.EventType
import com.simplemobiletools.commons.dialogs.ConfirmationDialog
import com.simplemobiletools.commons.dialogs.CustomIntervalPickerDialog
@ -58,9 +55,12 @@ class SettingsActivity : SimpleActivity() {
setupVibrate()
setupReminderSound()
setupUseSameSnooze()
setupLoopReminders()
setupSnoozeTime()
setupDisplayPastEvents()
setupFontSize()
setupCustomizeWidgetColors()
setupDimEvents()
updateTextColors(settings_holder)
checkPrimaryColor()
setupSectionColors()
@ -85,7 +85,7 @@ class SettingsActivity : SimpleActivity() {
private fun setupSectionColors() {
val adjustedPrimaryColor = getAdjustedPrimaryColor()
arrayListOf(reminders_label, caldav_label, weekly_view_label, monthly_view_label, simple_event_list_label, simple_font_size_label).forEach {
arrayListOf(reminders_label, caldav_label, weekly_view_label, monthly_view_label, simple_event_list_label, simple_font_size_label, events_label).forEach {
it.setTextColor(adjustedPrimaryColor)
}
}
@ -170,11 +170,13 @@ class SettingsActivity : SimpleActivity() {
settings_manage_synced_calendars_holder.beVisibleIf(newCalendarIds.isNotEmpty())
settings_caldav_sync.isChecked = newCalendarIds.isNotEmpty()
config.caldavSync = newCalendarIds.isNotEmpty()
toast(R.string.syncing)
if (settings_caldav_sync.isChecked) {
toast(R.string.syncing)
}
Thread {
if (newCalendarIds.isNotEmpty()) {
val existingEventTypeNames = dbHelper.fetchEventTypes().map { it.getDisplayTitle().toLowerCase() } as ArrayList<String>
val existingEventTypeNames = dbHelper.getEventTypesSync().map { it.getDisplayTitle().toLowerCase() } as ArrayList<String>
getSyncedCalDAVCalendars().forEach {
val calendarTitle = it.getFullTitle()
if (!existingEventTypeNames.contains(calendarTitle.toLowerCase())) {
@ -194,7 +196,9 @@ class SettingsActivity : SimpleActivity() {
}
}
dbHelper.deleteEventTypesWithCalendarId(TextUtils.join(",", removedCalendarIds))
toast(R.string.synchronization_completed)
if (settings_caldav_sync.isChecked) {
toast(R.string.synchronization_completed)
}
}.start()
}
}
@ -315,6 +319,14 @@ class SettingsActivity : SimpleActivity() {
}
}
private fun setupLoopReminders() {
settings_loop_reminders.isChecked = config.loopReminders
settings_loop_reminders_holder.setOnClickListener {
settings_loop_reminders.toggle()
config.loopReminders = settings_loop_reminders.isChecked
}
}
private fun setupUseSameSnooze() {
settings_snooze_time_holder.beVisibleIf(config.useSameSnooze)
settings_use_same_snooze.isChecked = config.useSameSnooze
@ -389,6 +401,23 @@ class SettingsActivity : SimpleActivity() {
else -> R.string.large
})
private fun setupCustomizeWidgetColors() {
settings_customize_widget_colors_holder.setOnClickListener {
Intent(this, WidgetListConfigureActivity::class.java).apply {
putExtra(IS_CUSTOMIZING_COLORS, true)
startActivity(this)
}
}
}
private fun setupDimEvents() {
settings_dim_past_events.isChecked = config.dimPastEvents
settings_dim_past_events_holder.setOnClickListener {
settings_dim_past_events.toggle()
config.dimPastEvents = settings_dim_past_events.isChecked
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, resultData: Intent?) {
super.onActivityResult(requestCode, resultCode, resultData)
if (requestCode == GET_RINGTONE_URI && resultCode == RESULT_OK && resultData != null) {

View File

@ -1,5 +1,30 @@
package com.simplemobiletools.calendar.activities
import com.simplemobiletools.calendar.R
import com.simplemobiletools.commons.activities.BaseSimpleActivity
open class SimpleActivity : BaseSimpleActivity()
open class SimpleActivity : BaseSimpleActivity() {
override fun getAppIconIDs() = arrayListOf(
R.mipmap.ic_launcher_red,
R.mipmap.ic_launcher_pink,
R.mipmap.ic_launcher_purple,
R.mipmap.ic_launcher_deep_purple,
R.mipmap.ic_launcher_indigo,
R.mipmap.ic_launcher_blue,
R.mipmap.ic_launcher_light_blue,
R.mipmap.ic_launcher_cyan,
R.mipmap.ic_launcher_teal,
R.mipmap.ic_launcher_green,
R.mipmap.ic_launcher_light_green,
R.mipmap.ic_launcher_lime,
R.mipmap.ic_launcher_yellow,
R.mipmap.ic_launcher_amber,
R.mipmap.ic_launcher,
R.mipmap.ic_launcher_deep_orange,
R.mipmap.ic_launcher_brown,
R.mipmap.ic_launcher_blue_grey,
R.mipmap.ic_launcher_grey_black
)
override fun getAppLauncherName() = getString(R.string.app_launcher_name)
}

View File

@ -3,7 +3,6 @@ package com.simplemobiletools.calendar.activities
import android.app.Activity
import android.appwidget.AppWidgetManager
import android.content.Intent
import android.content.res.Resources
import android.graphics.Color
import android.os.Bundle
import android.widget.SeekBar
@ -12,20 +11,19 @@ import com.simplemobiletools.calendar.adapters.EventListAdapter
import com.simplemobiletools.calendar.extensions.config
import com.simplemobiletools.calendar.extensions.seconds
import com.simplemobiletools.calendar.helpers.Formatter
import com.simplemobiletools.calendar.helpers.IS_CUSTOMIZING_COLORS
import com.simplemobiletools.calendar.helpers.MyWidgetListProvider
import com.simplemobiletools.calendar.models.ListEvent
import com.simplemobiletools.calendar.models.ListItem
import com.simplemobiletools.calendar.models.ListSection
import com.simplemobiletools.commons.dialogs.ColorPickerDialog
import com.simplemobiletools.commons.extensions.adjustAlpha
import com.simplemobiletools.commons.extensions.setFillWithStroke
import kotlinx.android.synthetic.main.widget_config_list.*
import org.joda.time.DateTime
import java.util.*
class WidgetListConfigureActivity : SimpleActivity() {
lateinit var mRes: Resources
private var mPackageName = ""
private var mBgAlpha = 0f
private var mWidgetId = 0
private var mBgColorWithoutTransparency = 0
@ -34,21 +32,21 @@ class WidgetListConfigureActivity : SimpleActivity() {
private var mTextColor = 0
private var mEventsAdapter: EventListAdapter? = null
private var mIsCustomizingColors = false
public override fun onCreate(savedInstanceState: Bundle?) {
useDynamicTheme = false
super.onCreate(savedInstanceState)
setResult(Activity.RESULT_CANCELED)
setContentView(R.layout.widget_config_list)
mPackageName = packageName
initVariables()
val extras = intent.extras
if (extras != null)
mWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID)
mIsCustomizingColors = intent.extras?.getBoolean(IS_CUSTOMIZING_COLORS) ?: false
mWidgetId = intent.extras?.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID) ?: AppWidgetManager.INVALID_APPWIDGET_ID
if (mWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID)
if (mWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID && !mIsCustomizingColors) {
finish()
}
mEventsAdapter = EventListAdapter(this, getListItems(), false, null, config_events_list) {}
mEventsAdapter!!.updateTextColor(mTextColor)
@ -68,8 +66,6 @@ class WidgetListConfigureActivity : SimpleActivity() {
}
private fun initVariables() {
mRes = resources
mTextColorWithoutTransparency = config.widgetTextColor
updateColors()
@ -107,15 +103,19 @@ class WidgetListConfigureActivity : SimpleActivity() {
private fun pickBackgroundColor() {
ColorPickerDialog(this, mBgColorWithoutTransparency) { wasPositivePressed, color ->
mBgColorWithoutTransparency = color
updateBgColor()
if (wasPositivePressed) {
mBgColorWithoutTransparency = color
updateBgColor()
}
}
}
private fun pickTextColor() {
ColorPickerDialog(this, mTextColor) { wasPositivePressed, color ->
mTextColorWithoutTransparency = color
updateColors()
if (wasPositivePressed) {
mTextColorWithoutTransparency = color
updateColors()
}
}
}
@ -129,14 +129,14 @@ class WidgetListConfigureActivity : SimpleActivity() {
private fun updateColors() {
mTextColor = mTextColorWithoutTransparency
mEventsAdapter?.updateTextColor(mTextColor)
config_text_color.setBackgroundColor(mTextColor)
config_text_color.setFillWithStroke(mTextColor, Color.BLACK)
config_save.setTextColor(mTextColor)
}
private fun updateBgColor() {
mBgColor = mBgColorWithoutTransparency.adjustAlpha(mBgAlpha)
config_events_list.setBackgroundColor(mBgColor)
config_bg_color.setBackgroundColor(mBgColor)
config_bg_color.setFillWithStroke(mBgColor, Color.BLACK)
config_save.setBackgroundColor(mBgColor)
}
@ -145,7 +145,7 @@ class WidgetListConfigureActivity : SimpleActivity() {
var dateTime = DateTime.now().withTime(0, 0, 0, 0).plusDays(1)
var code = Formatter.getDayCodeFromTS(dateTime.seconds())
var day = Formatter.getDayTitle(this, code)
listItems.add(ListSection(day, code))
listItems.add(ListSection(day, code, false, false))
var time = dateTime.withHourOfDay(7)
listItems.add(ListEvent(1, time.seconds(), time.plusMinutes(30).seconds(), getString(R.string.sample_title_1), getString(R.string.sample_description_1), false, config.primaryColor))
@ -155,7 +155,7 @@ class WidgetListConfigureActivity : SimpleActivity() {
dateTime = dateTime.plusDays(1)
code = Formatter.getDayCodeFromTS(dateTime.seconds())
day = Formatter.getDayTitle(this, code)
listItems.add(ListSection(day, code))
listItems.add(ListSection(day, code, false, false))
time = dateTime.withHourOfDay(8)
listItems.add(ListEvent(3, time.seconds(), time.plusHours(1).seconds(), getString(R.string.sample_title_3), "", false, config.primaryColor))

View File

@ -23,6 +23,7 @@ import com.simplemobiletools.commons.dialogs.ColorPickerDialog
import com.simplemobiletools.commons.extensions.adjustAlpha
import com.simplemobiletools.commons.extensions.applyColorFilter
import com.simplemobiletools.commons.extensions.beVisible
import com.simplemobiletools.commons.extensions.setFillWithStroke
import kotlinx.android.synthetic.main.first_row.*
import kotlinx.android.synthetic.main.top_navigation.*
import kotlinx.android.synthetic.main.widget_config_monthly.*
@ -111,16 +112,20 @@ class WidgetMonthlyConfigureActivity : SimpleActivity(), MonthlyCalendar {
private fun pickBackgroundColor() {
ColorPickerDialog(this, mBgColorWithoutTransparency) { wasPositivePressed, color ->
mBgColorWithoutTransparency = color
updateBgColor()
if (wasPositivePressed) {
mBgColorWithoutTransparency = color
updateBgColor()
}
}
}
private fun pickTextColor() {
ColorPickerDialog(this, mTextColor) { wasPositivePressed, color ->
mTextColorWithoutTransparency = color
updateColors()
updateDays()
if (wasPositivePressed) {
mTextColorWithoutTransparency = color
updateColors()
updateDays()
}
}
}
@ -139,7 +144,7 @@ class WidgetMonthlyConfigureActivity : SimpleActivity(), MonthlyCalendar {
top_left_arrow.applyColorFilter(mTextColor)
top_right_arrow.applyColorFilter(mTextColor)
top_value.setTextColor(mTextColor)
config_text_color.setBackgroundColor(mTextColor)
config_text_color.setFillWithStroke(mTextColor, Color.BLACK)
config_save.setTextColor(mTextColor)
updateLabels()
}
@ -147,7 +152,7 @@ class WidgetMonthlyConfigureActivity : SimpleActivity(), MonthlyCalendar {
private fun updateBgColor() {
mBgColor = mBgColorWithoutTransparency.adjustAlpha(mBgAlpha)
config_calendar.setBackgroundColor(mBgColor)
config_bg_color.setBackgroundColor(mBgColor)
config_bg_color.setFillWithStroke(mBgColor, Color.BLACK)
config_save.setBackgroundColor(mBgColor)
}

View File

@ -10,8 +10,10 @@ import com.simplemobiletools.calendar.extensions.config
import com.simplemobiletools.calendar.extensions.dbHelper
import com.simplemobiletools.calendar.extensions.shareEvents
import com.simplemobiletools.calendar.helpers.Formatter
import com.simplemobiletools.calendar.helpers.LOW_ALPHA
import com.simplemobiletools.calendar.models.Event
import com.simplemobiletools.commons.adapters.MyRecyclerViewAdapter
import com.simplemobiletools.commons.extensions.adjustAlpha
import com.simplemobiletools.commons.extensions.applyColorFilter
import com.simplemobiletools.commons.extensions.beInvisible
import com.simplemobiletools.commons.extensions.beInvisibleIf
@ -21,8 +23,9 @@ import kotlinx.android.synthetic.main.event_item_day_view.view.*
class DayEventsAdapter(activity: SimpleActivity, val events: ArrayList<Event>, recyclerView: MyRecyclerView, itemClick: (Any) -> Unit)
: MyRecyclerViewAdapter(activity, recyclerView, null, itemClick) {
private var allDayString = resources.getString(R.string.all_day)
private var replaceDescriptionWithLocation = activity.config.replaceDescription
private val allDayString = resources.getString(R.string.all_day)
private val replaceDescriptionWithLocation = activity.config.replaceDescription
private val dimPastEvents = activity.config.dimPastEvents
init {
setupDragListener(true)
@ -85,10 +88,15 @@ class DayEventsAdapter(activity: SimpleActivity, val events: ArrayList<Event>, r
}
}
event_item_start.setTextColor(textColor)
event_item_end.setTextColor(textColor)
event_section_title.setTextColor(textColor)
event_item_description.setTextColor(textColor)
var newTextColor = textColor
if (dimPastEvents && event.isPastEvent) {
newTextColor = newTextColor.adjustAlpha(LOW_ALPHA)
}
event_item_start.setTextColor(newTextColor)
event_item_end.setTextColor(newTextColor)
event_section_title.setTextColor(newTextColor)
event_item_description.setTextColor(newTextColor)
}
}

View File

@ -8,13 +8,15 @@ import com.simplemobiletools.calendar.activities.SimpleActivity
import com.simplemobiletools.calendar.dialogs.DeleteEventDialog
import com.simplemobiletools.calendar.extensions.config
import com.simplemobiletools.calendar.extensions.dbHelper
import com.simplemobiletools.calendar.extensions.getNowSeconds
import com.simplemobiletools.calendar.extensions.shareEvents
import com.simplemobiletools.calendar.helpers.Formatter
import com.simplemobiletools.calendar.helpers.LOW_ALPHA
import com.simplemobiletools.calendar.helpers.getNowSeconds
import com.simplemobiletools.calendar.models.ListEvent
import com.simplemobiletools.calendar.models.ListItem
import com.simplemobiletools.calendar.models.ListSection
import com.simplemobiletools.commons.adapters.MyRecyclerViewAdapter
import com.simplemobiletools.commons.extensions.adjustAlpha
import com.simplemobiletools.commons.extensions.applyColorFilter
import com.simplemobiletools.commons.extensions.beInvisible
import com.simplemobiletools.commons.extensions.beInvisibleIf
@ -23,7 +25,7 @@ import com.simplemobiletools.commons.views.MyRecyclerView
import kotlinx.android.synthetic.main.event_list_item.view.*
import java.util.*
class EventListAdapter(activity: SimpleActivity, val listItems: ArrayList<ListItem>, val allowLongClick: Boolean, val listener: RefreshRecyclerViewListener?,
class EventListAdapter(activity: SimpleActivity, var listItems: ArrayList<ListItem>, val allowLongClick: Boolean, val listener: RefreshRecyclerViewListener?,
recyclerView: MyRecyclerView, itemClick: (Any) -> Unit) : MyRecyclerViewAdapter(activity, recyclerView, null, itemClick) {
private val ITEM_EVENT = 0
@ -32,10 +34,27 @@ class EventListAdapter(activity: SimpleActivity, val listItems: ArrayList<ListIt
private val topDivider = resources.getDrawable(R.drawable.divider_width)
private val allDayString = resources.getString(R.string.all_day)
private val replaceDescriptionWithLocation = activity.config.replaceDescription
private val redTextColor = resources.getColor(R.color.red_text)
private val now = activity.getNowSeconds()
private val todayDate = Formatter.getDayTitle(activity, Formatter.getDayCodeFromTS(now))
private val dimPastEvents = activity.config.dimPastEvents
private val now = getNowSeconds()
private var use24HourFormat = activity.config.use24HourFormat
private var currentItemsHash = listItems.hashCode()
init {
var firstNonPastSectionIndex = -1
listItems.forEachIndexed { index, listItem ->
if (firstNonPastSectionIndex == -1 && listItem is ListSection) {
if (!listItem.isPastSection) {
firstNonPastSectionIndex = index
}
}
}
if (firstNonPastSectionIndex != -1) {
activity.runOnUiThread {
recyclerView.scrollToPosition(firstNonPastSectionIndex)
}
}
}
override fun getActionMenuId() = R.menu.cab_event_list
@ -82,6 +101,16 @@ class EventListAdapter(activity: SimpleActivity, val listItems: ArrayList<ListIt
notifyDataSetChanged()
}
fun updateListItems(newListItems: ArrayList<ListItem>) {
if (newListItems.hashCode() != currentItemsHash) {
currentItemsHash = newListItems.hashCode()
listItems = newListItems.clone() as ArrayList<ListItem>
recyclerView.resetItemCount()
notifyDataSetChanged()
finishActMode()
}
}
private fun setupListEvent(view: View, listEvent: ListEvent) {
view.apply {
event_section_title.text = listEvent.title
@ -112,12 +141,15 @@ class EventListAdapter(activity: SimpleActivity, val listItems: ArrayList<ListIt
var endTextColor = textColor
if (listEvent.startTS <= now && listEvent.endTS <= now) {
if (listEvent.isAllDay) {
if (Formatter.getDayCodeFromTS(listEvent.startTS) == Formatter.getDayCodeFromTS(now))
if (Formatter.getDayCodeFromTS(listEvent.startTS) == Formatter.getDayCodeFromTS(now)) {
startTextColor = primaryColor
} else {
startTextColor = redTextColor
}
}
if (dimPastEvents && listEvent.isPastEvent) {
startTextColor = startTextColor.adjustAlpha(LOW_ALPHA)
endTextColor = endTextColor.adjustAlpha(LOW_ALPHA)
}
endTextColor = redTextColor
} else if (listEvent.startTS <= now && listEvent.endTS >= now) {
startTextColor = primaryColor
}
@ -133,17 +165,23 @@ class EventListAdapter(activity: SimpleActivity, val listItems: ArrayList<ListIt
view.event_section_title.apply {
text = listSection.title
setCompoundDrawablesWithIntrinsicBounds(null, if (position == 0) null else topDivider, null, null)
setTextColor(if (listSection.title == todayDate) primaryColor else textColor)
var color = if (listSection.isToday) primaryColor else textColor
if (dimPastEvents && listSection.isPastSection) {
color = color.adjustAlpha(LOW_ALPHA)
}
setTextColor(color)
}
}
private fun shareEvents() {
val eventIds = ArrayList<Int>(selectedPositions.size)
selectedPositions.forEach {
eventIds.add((listItems[it] as ListEvent).id)
val item = listItems[it]
if (item is ListEvent) {
eventIds.add(item.id)
}
}
activity.shareEvents(eventIds.distinct())
finishActMode()
}
private fun askConfirmDelete() {
@ -151,8 +189,11 @@ class EventListAdapter(activity: SimpleActivity, val listItems: ArrayList<ListIt
val timestamps = ArrayList<Int>(selectedPositions.size)
selectedPositions.forEach {
eventIds.add((listItems[it] as ListEvent).id)
timestamps.add((listItems[it] as ListEvent).startTS)
val item = listItems[it]
if (item is ListEvent) {
eventIds.add(item.id)
timestamps.add(item.startTS)
}
}
DeleteEventDialog(activity, eventIds) {

View File

@ -11,13 +11,12 @@ import com.simplemobiletools.calendar.R.id.event_section_title
import com.simplemobiletools.calendar.extensions.config
import com.simplemobiletools.calendar.extensions.dbHelper
import com.simplemobiletools.calendar.extensions.seconds
import com.simplemobiletools.calendar.helpers.DAY_CODE
import com.simplemobiletools.calendar.helpers.EVENT_ID
import com.simplemobiletools.calendar.helpers.EVENT_OCCURRENCE_TS
import com.simplemobiletools.calendar.helpers.*
import com.simplemobiletools.calendar.helpers.Formatter
import com.simplemobiletools.calendar.models.ListEvent
import com.simplemobiletools.calendar.models.ListItem
import com.simplemobiletools.calendar.models.ListSection
import com.simplemobiletools.commons.extensions.adjustAlpha
import com.simplemobiletools.commons.extensions.getColoredBitmap
import com.simplemobiletools.commons.extensions.setText
import com.simplemobiletools.commons.extensions.setTextSize
@ -31,7 +30,9 @@ class EventListWidgetAdapter(val context: Context) : RemoteViewsService.RemoteVi
private val allDayString = context.resources.getString(R.string.all_day)
private var events = ArrayList<ListItem>()
private val textColor = context.config.widgetTextColor
private val weakTextColor = textColor.adjustAlpha(LOW_ALPHA)
private val replaceDescription = context.config.replaceDescription
private val dimPastEvents = context.config.dimPastEvents
private var mediumFontSize = context.config.getFontSize()
override fun getViewAt(position: Int): RemoteViews? {
@ -39,66 +40,84 @@ class EventListWidgetAdapter(val context: Context) : RemoteViewsService.RemoteVi
val remoteView: RemoteViews
if (type == ITEM_EVENT) {
val item = events[position] as ListEvent
remoteView = RemoteViews(context.packageName, R.layout.event_list_item_widget).apply {
setText(R.id.event_section_title, item.title)
setText(R.id.event_item_description, if (replaceDescription) item.location else item.description)
setText(R.id.event_item_start, if (item.isAllDay) allDayString else Formatter.getTimeFromTS(context, item.startTS))
setImageViewBitmap(R.id.event_item_color, context.resources.getColoredBitmap(R.drawable.monthly_event_dot, item.color))
if (item.startTS == item.endTS) {
setViewVisibility(R.id.event_item_end, View.INVISIBLE)
} else {
setViewVisibility(R.id.event_item_end, View.VISIBLE)
var endString = Formatter.getTimeFromTS(context, item.endTS)
val startCode = Formatter.getDayCodeFromTS(item.startTS)
val endCode = Formatter.getDayCodeFromTS(item.endTS)
if (startCode != endCode) {
if (item.isAllDay) {
endString = Formatter.getDateFromCode(context, endCode, true)
} else {
endString += " (${Formatter.getDateFromCode(context, endCode, true)})"
}
} else if (item.isAllDay) {
setViewVisibility(R.id.event_item_end, View.INVISIBLE)
}
setText(R.id.event_item_end, endString)
}
setTextColor(R.id.event_section_title, textColor)
setTextColor(R.id.event_item_description, textColor)
setTextColor(R.id.event_item_start, textColor)
setTextColor(R.id.event_item_end, textColor)
setTextSize(R.id.event_section_title, mediumFontSize)
setTextSize(R.id.event_item_description, mediumFontSize)
setTextSize(R.id.event_item_start, mediumFontSize)
setTextSize(R.id.event_item_end, mediumFontSize)
Intent().apply {
putExtra(EVENT_ID, item.id)
putExtra(EVENT_OCCURRENCE_TS, item.startTS)
setOnClickFillInIntent(event_item_holder, this)
}
}
remoteView = RemoteViews(context.packageName, R.layout.event_list_item_widget)
setupListEvent(remoteView, events[position] as ListEvent)
} else {
val item = events[position] as ListSection
remoteView = RemoteViews(context.packageName, R.layout.event_list_section_widget).apply {
setTextColor(R.id.event_section_title, textColor)
setTextSize(R.id.event_section_title, mediumFontSize)
setText(R.id.event_section_title, item.title)
Intent().apply {
putExtra(DAY_CODE, item.code)
setOnClickFillInIntent(event_section_title, this)
}
}
remoteView = RemoteViews(context.packageName, R.layout.event_list_section_widget)
setupListSection(remoteView, events[position] as ListSection)
}
return remoteView
}
private fun setupListEvent(remoteView: RemoteViews, item: ListEvent) {
var curTextColor = textColor
remoteView.apply {
setText(R.id.event_section_title, item.title)
setText(R.id.event_item_description, if (replaceDescription) item.location else item.description)
setText(R.id.event_item_start, if (item.isAllDay) allDayString else Formatter.getTimeFromTS(context, item.startTS))
setImageViewBitmap(R.id.event_item_color, context.resources.getColoredBitmap(R.drawable.monthly_event_dot, item.color))
if (item.startTS == item.endTS) {
setViewVisibility(R.id.event_item_end, View.INVISIBLE)
} else {
setViewVisibility(R.id.event_item_end, View.VISIBLE)
var endString = Formatter.getTimeFromTS(context, item.endTS)
val startCode = Formatter.getDayCodeFromTS(item.startTS)
val endCode = Formatter.getDayCodeFromTS(item.endTS)
if (startCode != endCode) {
if (item.isAllDay) {
endString = Formatter.getDateFromCode(context, endCode, true)
} else {
endString += " (${Formatter.getDateFromCode(context, endCode, true)})"
}
} else if (item.isAllDay) {
setViewVisibility(R.id.event_item_end, View.INVISIBLE)
}
setText(R.id.event_item_end, endString)
}
if (dimPastEvents && item.isPastEvent) {
curTextColor = weakTextColor
}
setTextColor(R.id.event_section_title, curTextColor)
setTextColor(R.id.event_item_description, curTextColor)
setTextColor(R.id.event_item_start, curTextColor)
setTextColor(R.id.event_item_end, curTextColor)
setTextSize(R.id.event_section_title, mediumFontSize)
setTextSize(R.id.event_item_description, mediumFontSize)
setTextSize(R.id.event_item_start, mediumFontSize)
setTextSize(R.id.event_item_end, mediumFontSize)
Intent().apply {
putExtra(EVENT_ID, item.id)
putExtra(EVENT_OCCURRENCE_TS, item.startTS)
setOnClickFillInIntent(event_item_holder, this)
}
}
}
private fun setupListSection(remoteView: RemoteViews, item: ListSection) {
var curTextColor = textColor
if (dimPastEvents && item.isPastSection) {
curTextColor = weakTextColor
}
remoteView.apply {
setTextColor(R.id.event_section_title, curTextColor)
setTextSize(R.id.event_section_title, mediumFontSize)
setText(R.id.event_section_title, item.title)
Intent().apply {
putExtra(DAY_CODE, item.code)
setOnClickFillInIntent(event_section_title, this)
}
}
}
private fun getItemViewType(position: Int) = if (events[position] is ListEvent) ITEM_EVENT else ITEM_HEADER
override fun getLoadingView() = null
@ -117,16 +136,22 @@ class EventListWidgetAdapter(val context: Context) : RemoteViewsService.RemoteVi
val listItems = ArrayList<ListItem>(it.size)
val replaceDescription = context.config.replaceDescription
val sorted = it.sortedWith(compareBy({ it.startTS }, { it.endTS }, { it.title }, { if (replaceDescription) it.location else it.description }))
val sublist = sorted.subList(0, Math.min(sorted.size, 100))
var prevCode = ""
sublist.forEach {
val now = getNowSeconds()
val today = Formatter.getDayTitle(context, Formatter.getDayCodeFromTS(now))
sorted.forEach {
val code = Formatter.getDayCodeFromTS(it.startTS)
if (code != prevCode) {
val day = Formatter.getDayTitle(context, code)
listItems.add(ListSection(day, code))
val isToday = day == today
val listSection = ListSection(day, code, isToday, !isToday && it.startTS < now)
listItems.add(listSection)
prevCode = code
}
listItems.add(ListEvent(it.id, it.startTS, it.endTS, it.title, it.description, it.getIsAllDay(), it.color, it.location))
val listEvent = ListEvent(it.id, it.startTS, it.endTS, it.title, it.description, it.getIsAllDay(), it.color, it.location, it.isPastEvent)
listItems.add(listEvent)
}
this@EventListWidgetAdapter.events = listItems

View File

@ -9,7 +9,7 @@ import com.simplemobiletools.calendar.activities.SimpleActivity
import com.simplemobiletools.calendar.extensions.config
import com.simplemobiletools.calendar.models.EventType
import com.simplemobiletools.commons.extensions.getAdjustedPrimaryColor
import com.simplemobiletools.commons.extensions.setBackgroundWithStroke
import com.simplemobiletools.commons.extensions.setFillWithStroke
import com.simplemobiletools.commons.interfaces.MyAdapterListener
import kotlinx.android.synthetic.main.filter_event_type_view.view.*
import java.util.*
@ -73,7 +73,7 @@ class FilterEventTypeAdapter(val activity: SimpleActivity, val eventTypes: List<
itemView.apply {
filter_event_type_checkbox.setColors(activity.config.textColor, activity.getAdjustedPrimaryColor(), activity.config.backgroundColor)
filter_event_type_checkbox.text = eventType.getDisplayTitle()
filter_event_type_color.setBackgroundWithStroke(eventType.color, activity.config.backgroundColor)
filter_event_type_color.setFillWithStroke(eventType.color, activity.config.backgroundColor)
filter_event_type_holder.setOnClickListener { viewClicked(!filter_event_type_checkbox.isChecked) }
}

View File

@ -13,7 +13,7 @@ import com.simplemobiletools.calendar.models.EventType
import com.simplemobiletools.commons.adapters.MyRecyclerViewAdapter
import com.simplemobiletools.commons.dialogs.ConfirmationDialog
import com.simplemobiletools.commons.dialogs.RadioGroupDialog
import com.simplemobiletools.commons.extensions.setBackgroundWithStroke
import com.simplemobiletools.commons.extensions.setFillWithStroke
import com.simplemobiletools.commons.extensions.toast
import com.simplemobiletools.commons.models.RadioItem
import com.simplemobiletools.commons.views.MyRecyclerView
@ -60,7 +60,7 @@ class ManageEventTypesAdapter(activity: SimpleActivity, val eventTypes: ArrayLis
private fun setupView(view: View, eventType: EventType) {
view.apply {
event_type_title.text = eventType.getDisplayTitle()
event_type_color.setBackgroundWithStroke(eventType.color, activity.config.backgroundColor)
event_type_color.setFillWithStroke(eventType.color, activity.config.backgroundColor)
event_type_title.setTextColor(textColor)
}
}

View File

@ -14,7 +14,7 @@ class FilterEventTypesDialog(val activity: SimpleActivity, val callback: () -> U
val view = activity.layoutInflater.inflate(R.layout.dialog_filter_event_types, null)
init {
val eventTypes = activity.dbHelper.fetchEventTypes()
val eventTypes = activity.dbHelper.getEventTypesSync()
val displayEventTypes = activity.config.displayEventTypes
view.filter_event_types_list.adapter = FilterEventTypeAdapter(activity, eventTypes, displayEventTypes)

View File

@ -9,7 +9,7 @@ import com.simplemobiletools.calendar.extensions.dbHelper
import com.simplemobiletools.calendar.helpers.DBHelper
import com.simplemobiletools.calendar.helpers.IcsImporter
import com.simplemobiletools.calendar.helpers.IcsImporter.ImportResult.*
import com.simplemobiletools.commons.extensions.setBackgroundWithStroke
import com.simplemobiletools.commons.extensions.setFillWithStroke
import com.simplemobiletools.commons.extensions.setupDialogStuff
import com.simplemobiletools.commons.extensions.toast
import kotlinx.android.synthetic.main.dialog_import_events.view.*
@ -19,12 +19,34 @@ class ImportEventsDialog(val activity: SimpleActivity, val path: String, val cal
var currEventTypeCalDAVCalendarId = 0
init {
val config = activity.config
if (activity.dbHelper.getEventType(config.lastUsedLocalEventTypeId) == null) {
config.lastUsedLocalEventTypeId = DBHelper.REGULAR_EVENT_TYPE_ID
}
val isLastCaldavCalendarOK = config.caldavSync && config.getSyncedCalendarIdsAsList().contains(config.lastUsedCaldavCalendarId.toString())
currEventTypeId = if (isLastCaldavCalendarOK) {
val lastUsedCalDAVCalendar = activity.dbHelper.getEventTypeWithCalDAVCalendarId(config.lastUsedCaldavCalendarId)
if (lastUsedCalDAVCalendar != null) {
currEventTypeCalDAVCalendarId = config.lastUsedCaldavCalendarId
lastUsedCalDAVCalendar.id
} else {
DBHelper.REGULAR_EVENT_TYPE_ID
}
} else {
config.lastUsedLocalEventTypeId
}
val view = (activity.layoutInflater.inflate(R.layout.dialog_import_events, null) as ViewGroup).apply {
updateEventType(this)
import_event_type_holder.setOnClickListener {
SelectEventTypeDialog(activity, currEventTypeId, true) {
currEventTypeId = it.id
currEventTypeCalDAVCalendarId = it.caldavCalendarId
config.lastUsedLocalEventTypeId = it.id
config.lastUsedCaldavCalendarId = it.caldavCalendarId
updateEventType(this)
}
}
@ -38,7 +60,8 @@ class ImportEventsDialog(val activity: SimpleActivity, val path: String, val cal
getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener {
activity.toast(R.string.importing)
Thread {
val result = IcsImporter(activity).importEvents(path, currEventTypeId, currEventTypeCalDAVCalendarId)
val overrideFileEventTypes = view.import_events_checkbox.isChecked
val result = IcsImporter(activity).importEvents(path, currEventTypeId, currEventTypeCalDAVCalendarId, overrideFileEventTypes)
handleParseResult(result)
dismiss()
}.start()
@ -50,7 +73,7 @@ class ImportEventsDialog(val activity: SimpleActivity, val path: String, val cal
private fun updateEventType(view: ViewGroup) {
val eventType = activity.dbHelper.getEventType(currEventTypeId)
view.import_event_type_title.text = eventType!!.getDisplayTitle()
view.import_event_type_color.setBackgroundWithStroke(eventType.color, activity.config.backgroundColor)
view.import_event_type_color.setFillWithStroke(eventType.color, activity.config.backgroundColor)
}
private fun handleParseResult(result: IcsImporter.ImportResult) {

View File

@ -7,9 +7,9 @@ import android.support.v7.app.AlertDialog
import android.view.View
import com.simplemobiletools.calendar.R
import com.simplemobiletools.calendar.extensions.config
import com.simplemobiletools.calendar.extensions.getNowSeconds
import com.simplemobiletools.calendar.extensions.seconds
import com.simplemobiletools.calendar.helpers.Formatter
import com.simplemobiletools.calendar.helpers.getNowSeconds
import com.simplemobiletools.commons.extensions.getDialogTheme
import com.simplemobiletools.commons.extensions.setupDialogStuff
import com.simplemobiletools.commons.extensions.value
@ -57,7 +57,7 @@ class RepeatLimitTypePickerDialog(val activity: Activity, var repeatLimit: Int,
private fun updateRepeatLimitText() {
if (repeatLimit <= 0)
repeatLimit = activity.getNowSeconds()
repeatLimit = getNowSeconds()
val repeatLimitDateTime = Formatter.getDateTimeFromTS(repeatLimit)
view.repeat_type_date.text = Formatter.getFullDate(activity, repeatLimitDateTime)
@ -82,7 +82,7 @@ class RepeatLimitTypePickerDialog(val activity: Activity, var repeatLimit: Int,
@SuppressLint("NewApi")
private fun showRepetitionLimitDialog() {
val repeatLimitDateTime = Formatter.getDateTimeFromTS(if (repeatLimit != 0) repeatLimit else activity.getNowSeconds())
val repeatLimitDateTime = Formatter.getDateTimeFromTS(if (repeatLimit != 0) repeatLimit else getNowSeconds())
val datepicker = DatePickerDialog(activity, activity.getDialogTheme(), repetitionLimitDateSetListener, repeatLimitDateTime.year,
repeatLimitDateTime.monthOfYear - 1, repeatLimitDateTime.dayOfMonth)

View File

@ -11,7 +11,7 @@ import com.simplemobiletools.calendar.extensions.config
import com.simplemobiletools.calendar.extensions.dbHelper
import com.simplemobiletools.calendar.helpers.STORED_LOCALLY_ONLY
import com.simplemobiletools.calendar.models.CalDAVCalendar
import com.simplemobiletools.commons.extensions.setBackgroundWithStroke
import com.simplemobiletools.commons.extensions.setFillWithStroke
import com.simplemobiletools.commons.extensions.setupDialogStuff
import com.simplemobiletools.commons.extensions.updateTextColors
import kotlinx.android.synthetic.main.dialog_select_radio_group.view.*
@ -52,7 +52,7 @@ class SelectEventCalendarDialog(val activity: Activity, val calendars: List<CalD
}
if (color != Color.TRANSPARENT)
view.dialog_radio_color.setBackgroundWithStroke(color, activity.config.backgroundColor)
view.dialog_radio_color.setFillWithStroke(color, activity.config.backgroundColor)
view.setOnClickListener { viewClicked(typeId) }
radioGroup.addView(view, RadioGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT))

View File

@ -10,7 +10,7 @@ import com.simplemobiletools.calendar.R
import com.simplemobiletools.calendar.extensions.config
import com.simplemobiletools.calendar.helpers.CalDAVHandler
import com.simplemobiletools.calendar.models.EventType
import com.simplemobiletools.commons.extensions.setBackgroundWithStroke
import com.simplemobiletools.commons.extensions.setFillWithStroke
import com.simplemobiletools.commons.extensions.setupDialogStuff
import kotlinx.android.synthetic.main.dialog_select_radio_group.view.*
import kotlinx.android.synthetic.main.radio_button_with_color.view.*
@ -45,7 +45,7 @@ class SelectEventTypeColorDialog(val activity: Activity, val eventType: EventTyp
}
if (color != Color.TRANSPARENT)
view.dialog_radio_color.setBackgroundWithStroke(color, activity.config.backgroundColor)
view.dialog_radio_color.setFillWithStroke(color, activity.config.backgroundColor)
view.setOnClickListener { viewClicked(colorKey) }
radioGroup.addView(view, RadioGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT))

View File

@ -10,7 +10,7 @@ import com.simplemobiletools.calendar.extensions.config
import com.simplemobiletools.calendar.extensions.dbHelper
import com.simplemobiletools.calendar.models.EventType
import com.simplemobiletools.commons.extensions.hideKeyboard
import com.simplemobiletools.commons.extensions.setBackgroundWithStroke
import com.simplemobiletools.commons.extensions.setFillWithStroke
import com.simplemobiletools.commons.extensions.setupDialogStuff
import com.simplemobiletools.commons.extensions.updateTextColors
import com.simplemobiletools.commons.views.MyCompatRadioButton
@ -59,7 +59,7 @@ class SelectEventTypeDialog(val activity: Activity, val currEventType: Int, val
}
if (eventType.color != Color.TRANSPARENT) {
view.dialog_radio_color.setBackgroundWithStroke(eventType.color, activity.config.backgroundColor)
view.dialog_radio_color.setFillWithStroke(eventType.color, activity.config.backgroundColor)
}
view.setOnClickListener { viewClicked(eventType) }

View File

@ -24,8 +24,10 @@ class UpdateEventTypeDialog(val activity: Activity, var eventType: EventType? =
type_color.setOnClickListener {
if (eventType?.caldavCalendarId == 0) {
ColorPickerDialog(activity, eventType!!.color) { wasPositivePressed, color ->
eventType!!.color = color
setupColor(type_color)
if (wasPositivePressed) {
eventType!!.color = color
setupColor(type_color)
}
}
} else {
SelectEventTypeColorDialog(activity, eventType!!) {
@ -79,6 +81,6 @@ class UpdateEventTypeDialog(val activity: Activity, var eventType: EventType? =
}
private fun setupColor(view: ImageView) {
view.setBackgroundWithStroke(eventType!!.color, activity.config.backgroundColor)
view.setFillWithStroke(eventType!!.color, activity.config.backgroundColor)
}
}

View File

@ -33,7 +33,9 @@ import com.simplemobiletools.calendar.receivers.CalDAVSyncReceiver
import com.simplemobiletools.calendar.receivers.NotificationReceiver
import com.simplemobiletools.calendar.services.SnoozeService
import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.DAY_SECONDS
import com.simplemobiletools.commons.helpers.SILENT
import com.simplemobiletools.commons.helpers.YEAR_SECONDS
import com.simplemobiletools.commons.helpers.isOreoPlus
import org.joda.time.DateTime
import org.joda.time.DateTimeZone
@ -45,8 +47,6 @@ val Context.config: Config get() = Config.newInstance(applicationContext)
val Context.dbHelper: DBHelper get() = DBHelper.newInstance(applicationContext)
fun Context.getNowSeconds() = (System.currentTimeMillis() / 1000).toInt()
fun Context.updateWidgets() {
val widgetIDs = AppWidgetManager.getInstance(applicationContext).getAppWidgetIds(ComponentName(applicationContext, MyWidgetMonthlyProvider::class.java))
if (widgetIDs.isNotEmpty()) {
@ -137,20 +137,35 @@ fun Context.getRepetitionText(seconds: Int) = when (seconds) {
}
}
fun Context.getFilteredEvents(events: List<Event>): List<Event> {
fun Context.getFilteredEvents(events: List<Event>): ArrayList<Event> {
val displayEventTypes = config.displayEventTypes
return events.filter { displayEventTypes.contains(it.eventType.toString()) }
return events.filter { displayEventTypes.contains(it.eventType.toString()) } as ArrayList<Event>
}
fun Context.notifyRunningEvents() {
dbHelper.getRunningEvents().forEach { notifyEvent(it) }
}
fun Context.notifyEvent(event: Event) {
fun Context.notifyEvent(originalEvent: Event) {
var event = originalEvent.copy()
val currentSeconds = getNowSeconds()
// make sure refer to the proper repeatable event instance with "Tomorrow", or the specific date
if (event.repeatInterval != 0 && event.startTS - event.reminder1Minutes * 60 < currentSeconds) {
val events = dbHelper.getRepeatableEventsFor(currentSeconds - DAY_SECONDS, currentSeconds + YEAR_SECONDS, event.id)
for (currEvent in events) {
event = currEvent
if (event.startTS - event.reminder1Minutes * 60 > currentSeconds) {
break
}
}
}
val pendingIntent = getPendingIntent(applicationContext, event)
val startTime = Formatter.getTimeFromTS(applicationContext, event.startTS)
val endTime = Formatter.getTimeFromTS(applicationContext, event.endTS)
val startDate = Formatter.getDateFromTS(event.startTS)
val displayedStartDate = when (startDate) {
LocalDate.now() -> ""
LocalDate.now().plusDays(1) -> getString(R.string.tomorrow)
@ -211,14 +226,19 @@ fun Context.getNotification(pendingIntent: PendingIntent, event: Event, content:
.addAction(R.drawable.ic_snooze, getString(R.string.snooze), getSnoozePendingIntent(this, event))
if (config.vibrateOnReminder) {
builder.setVibrate(longArrayOf(0, 300, 300, 300))
val vibrateArray = LongArray(2) { 500 }
builder.setVibrate(vibrateArray)
}
if (!publicVersion) {
builder.setPublicVersion(getNotification(pendingIntent, event, content, true))
}
return builder.build()
val notification = builder.build()
if (config.loopReminders) {
notification.flags = notification.flags or Notification.FLAG_INSISTENT
}
return notification
}
private fun getFormattedEventTime(startTime: String, endTime: String) = if (startTime == endTime) startTime else "$startTime \u2013 $endTime"
@ -346,8 +366,8 @@ fun Context.addDayNumber(rawTextColor: Int, day: DayMonthly, linearLayout: Linea
}
}
private fun addTodaysBackground(textView: TextView, res: Resources, dayLabelHeight: Int, mPrimaryColor: Int) =
textView.addResizedBackgroundDrawable(res, dayLabelHeight, mPrimaryColor, R.drawable.ic_circle_filled)
private fun addTodaysBackground(textView: TextView, res: Resources, dayLabelHeight: Int, primaryColor: Int) =
textView.addResizedBackgroundDrawable(res, dayLabelHeight, primaryColor, R.drawable.ic_circle_filled)
fun Context.addDayEvents(day: DayMonthly, linearLayout: LinearLayout, res: Resources, dividerMargin: Int) {
val eventLayoutParams = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
@ -377,16 +397,21 @@ fun Context.getEventListItems(events: List<Event>): ArrayList<ListItem> {
val listItems = ArrayList<ListItem>(events.size)
val replaceDescription = config.replaceDescription
val sorted = events.sortedWith(compareBy({ it.startTS }, { it.endTS }, { it.title }, { if (replaceDescription) it.location else it.description }))
val sublist = sorted.subList(0, Math.min(sorted.size, 100))
var prevCode = ""
sublist.forEach {
val now = getNowSeconds()
val today = Formatter.getDayTitle(this, Formatter.getDayCodeFromTS(now))
sorted.forEach {
val code = Formatter.getDayCodeFromTS(it.startTS)
if (code != prevCode) {
val day = Formatter.getDayTitle(this, code)
listItems.add(ListSection(day, code))
val isToday = day == today
val listSection = ListSection(day, code, isToday, !isToday && it.startTS < now)
listItems.add(listSection)
prevCode = code
}
listItems.add(ListEvent(it.id, it.startTS, it.endTS, it.title, it.description, it.getIsAllDay(), it.color, it.location))
val listEvent = ListEvent(it.id, it.startTS, it.endTS, it.title, it.description, it.getIsAllDay(), it.color, it.location, it.isPastEvent)
listItems.add(listEvent)
}
return listItems
}

View File

@ -3,6 +3,7 @@ package com.simplemobiletools.calendar.extensions
import com.simplemobiletools.calendar.helpers.Formatter
import com.simplemobiletools.calendar.helpers.MONTH
import com.simplemobiletools.calendar.helpers.WEEK
import com.simplemobiletools.calendar.helpers.YEAR
import com.simplemobiletools.calendar.models.Event
fun Int.isTsOnProperDay(event: Event): Boolean {
@ -14,3 +15,5 @@ fun Int.isTsOnProperDay(event: Event): Boolean {
fun Int.isXWeeklyRepetition() = this != 0 && this % WEEK == 0
fun Int.isXMonthlyRepetition() = this != 0 && this % MONTH == 0
fun Int.isXYearlyRepetition() = this != 0 && this % YEAR == 0

View File

@ -1,7 +1,6 @@
package com.simplemobiletools.calendar.fragments
import android.content.Intent
import android.content.res.Resources
import android.os.Bundle
import android.support.v4.app.Fragment
import android.support.v7.app.AlertDialog
@ -37,12 +36,10 @@ class DayFragment : Fragment() {
private var mDayCode = ""
private var lastHash = 0
lateinit var mRes: Resources
lateinit var mHolder: RelativeLayout
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view = inflater.inflate(R.layout.fragment_day, container, false)
mRes = resources
mHolder = view.day_holder
mDayCode = arguments!!.getString(DAY_CODE)

View File

@ -19,7 +19,7 @@ import org.joda.time.DateTime
import java.util.*
class DayFragmentsHolder : MyFragmentHolder(), NavigationListener {
private val PREFILLED_DAYS = 121
private val PREFILLED_DAYS = 251
private var viewPager: MyViewPager? = null
private var defaultDailyPage = 0

View File

@ -19,23 +19,40 @@ import com.simplemobiletools.calendar.models.Event
import com.simplemobiletools.calendar.models.ListEvent
import com.simplemobiletools.commons.extensions.beGoneIf
import com.simplemobiletools.commons.extensions.beVisibleIf
import com.simplemobiletools.commons.extensions.getAdjustedPrimaryColor
import com.simplemobiletools.commons.extensions.underlineText
import com.simplemobiletools.commons.helpers.MONTH_SECONDS
import com.simplemobiletools.commons.interfaces.RefreshRecyclerViewListener
import com.simplemobiletools.commons.views.MyRecyclerView
import kotlinx.android.synthetic.main.fragment_event_list.view.*
import org.joda.time.DateTime
import java.util.*
class EventListFragment : MyFragmentHolder(), RefreshRecyclerViewListener {
private var mEvents: List<Event> = ArrayList()
private var prevEventsHash = 0
private var FETCH_INTERVAL = 6 * MONTH_SECONDS
private var MIN_EVENTS_TRESHOLD = 30
private var mEvents = ArrayList<Event>()
private var minFetchedTS = 0
private var maxFetchedTS = 0
private var wereInitialEventsAdded = false
private var use24HourFormat = false
lateinit var mView: View
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
mView = inflater.inflate(R.layout.fragment_event_list, container, false)
val placeholderText = String.format(getString(R.string.two_string_placeholder), "${getString(R.string.no_upcoming_events)}\n", getString(R.string.add_some_events))
mView.calendar_empty_list_placeholder.text = placeholderText
mView.background = ColorDrawable(context!!.config.backgroundColor)
mView.calendar_events_list_holder?.id = (System.currentTimeMillis() % 100000).toInt()
mView.calendar_empty_list_placeholder_2.apply {
setTextColor(context.getAdjustedPrimaryColor())
underlineText()
setOnClickListener {
context.launchNewEventIntent(getNewEventDayCode())
}
}
use24HourFormat = context!!.config.use24HourFormat
updateActionBarTitle()
return mView
@ -57,42 +74,69 @@ class EventListFragment : MyFragmentHolder(), RefreshRecyclerViewListener {
}
private fun checkEvents() {
val fromTS = DateTime().seconds() - context!!.config.displayPastEvents * 60
val toTS = DateTime().plusYears(1).seconds()
context!!.dbHelper.getEvents(fromTS, toTS) {
receivedEvents(it)
if (!wereInitialEventsAdded) {
minFetchedTS = DateTime().minusMonths(3).seconds()
maxFetchedTS = DateTime().plusMonths(6).seconds()
}
context!!.dbHelper.getEvents(minFetchedTS, maxFetchedTS) {
if (it.size >= MIN_EVENTS_TRESHOLD) {
receivedEvents(it, false)
} else {
if (!wereInitialEventsAdded) {
minFetchedTS -= FETCH_INTERVAL
maxFetchedTS += FETCH_INTERVAL
}
context!!.dbHelper.getEvents(minFetchedTS, maxFetchedTS) {
mEvents = it
receivedEvents(mEvents, false, !wereInitialEventsAdded)
}
}
wereInitialEventsAdded = true
}
}
private fun receivedEvents(events: MutableList<Event>) {
private fun receivedEvents(events: ArrayList<Event>, scrollAfterUpdating: Boolean, forceRecreation: Boolean = false) {
if (context == null || activity == null) {
return
}
val filtered = context!!.getFilteredEvents(events)
val hash = filtered.hashCode()
if (prevEventsHash == hash) {
return
}
prevEventsHash = hash
mEvents = filtered
mEvents = context!!.getFilteredEvents(events)
val listItems = context!!.getEventListItems(mEvents)
val eventsAdapter = EventListAdapter(activity as SimpleActivity, listItems, true, this, mView.calendar_events_list) {
if (it is ListEvent) {
editEvent(it)
}
}
activity?.runOnUiThread {
mView.calendar_events_list.adapter = eventsAdapter
val currAdapter = mView.calendar_events_list.adapter
if (currAdapter == null || forceRecreation) {
EventListAdapter(activity as SimpleActivity, listItems, true, this, mView.calendar_events_list) {
if (it is ListEvent) {
editEvent(it)
}
}.apply {
mView.calendar_events_list.adapter = this
}
mView.calendar_events_list.endlessScrollListener = object : MyRecyclerView.EndlessScrollListener {
override fun updateTop() {
fetchPreviousPeriod()
}
override fun updateBottom() {
fetchNextPeriod(true)
}
}
} else {
(currAdapter as EventListAdapter).updateListItems(listItems)
if (scrollAfterUpdating) {
mView.calendar_events_list.smoothScrollBy(0, context!!.resources.getDimension(R.dimen.endless_scroll_move_height).toInt())
}
}
checkPlaceholderVisibility()
}
}
private fun checkPlaceholderVisibility() {
mView.calendar_empty_list_placeholder.beVisibleIf(mEvents.isEmpty())
mView.calendar_empty_list_placeholder_2.beVisibleIf(mEvents.isEmpty())
mView.calendar_events_list.beGoneIf(mEvents.isEmpty())
if (activity != null)
mView.calendar_empty_list_placeholder.setTextColor(activity!!.config.textColor)
@ -106,6 +150,24 @@ class EventListFragment : MyFragmentHolder(), RefreshRecyclerViewListener {
}
}
private fun fetchPreviousPeriod() {
val oldMinFetchedTS = minFetchedTS - 1
minFetchedTS -= FETCH_INTERVAL
context!!.dbHelper.getEvents(minFetchedTS, oldMinFetchedTS) {
mEvents.addAll(0, it)
receivedEvents(mEvents, false)
}
}
private fun fetchNextPeriod(scrollAfterUpdating: Boolean) {
val oldMaxFetchedTS = maxFetchedTS + 1
maxFetchedTS += FETCH_INTERVAL
context!!.dbHelper.getEvents(oldMaxFetchedTS, maxFetchedTS) {
mEvents.addAll(it)
receivedEvents(mEvents, scrollAfterUpdating)
}
}
override fun refreshItems() {
checkEvents()
}

View File

@ -19,7 +19,7 @@ import kotlinx.android.synthetic.main.fragment_months_holder.view.*
import org.joda.time.DateTime
class MonthFragmentsHolder : MyFragmentHolder(), NavigationListener {
private val PREFILLED_MONTHS = 97
private val PREFILLED_MONTHS = 251
private var viewPager: MyViewPager? = null
private var defaultMonthlyPage = 0

View File

@ -24,6 +24,8 @@ import com.simplemobiletools.calendar.interfaces.WeeklyCalendar
import com.simplemobiletools.calendar.models.Event
import com.simplemobiletools.calendar.views.MyScrollView
import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.DAY_SECONDS
import com.simplemobiletools.commons.helpers.WEEK_SECONDS
import kotlinx.android.synthetic.main.fragment_week.*
import kotlinx.android.synthetic.main.fragment_week.view.*
import org.joda.time.DateTime
@ -45,6 +47,7 @@ class WeekFragment : Fragment(), WeeklyCalendar {
private var isFragmentVisible = false
private var wasFragmentInit = false
private var wasExtraHeightAdded = false
private var dimPastEvents = true
private var clickStartTime = 0L
private var selectedGrid: View? = null
private var todayColumnIndex = -1
@ -68,6 +71,7 @@ class WeekFragment : Fragment(), WeeklyCalendar {
mRowHeight = (context!!.resources.getDimension(R.dimen.weekly_view_row_height)).toInt()
minScrollY = mRowHeight * context!!.config.startWeeklyAt
mWeekTimestamp = arguments!!.getInt(WEEK_START_TIMESTAMP)
dimPastEvents = context!!.config.dimPastEvents
primaryColor = context!!.getAdjustedPrimaryColor()
mRes = resources
allDayRows.add(HashSet())
@ -270,9 +274,15 @@ class WeekFragment : Fragment(), WeeklyCalendar {
val duration = endDateTime.minuteOfDay - startMinutes
(inflater.inflate(R.layout.week_event_marker, null, false) as TextView).apply {
val backgroundColor = eventTypeColors.get(event.eventType, primaryColor)
var backgroundColor = eventTypeColors.get(event.eventType, primaryColor)
var textColor = backgroundColor.getContrastColor()
if (dimPastEvents && event.isPastEvent) {
backgroundColor = backgroundColor.adjustAlpha(LOW_ALPHA)
textColor = textColor.adjustAlpha(LOW_ALPHA)
}
background = ColorDrawable(backgroundColor)
setTextColor(backgroundColor.getContrastColor())
setTextColor(textColor)
text = event.title
layout.addView(this)
y = startMinutes * minuteHeight
@ -339,9 +349,15 @@ class WeekFragment : Fragment(), WeeklyCalendar {
if (activity == null)
return
val backgroundColor = eventTypeColors.get(event.eventType, primaryColor)
var backgroundColor = eventTypeColors.get(event.eventType, primaryColor)
var textColor = backgroundColor.getContrastColor()
if (dimPastEvents && event.isPastEvent) {
backgroundColor = backgroundColor.adjustAlpha(LOW_ALPHA)
textColor = textColor.adjustAlpha(LOW_ALPHA)
}
background = ColorDrawable(backgroundColor)
setTextColor(backgroundColor.getContrastColor())
setTextColor(textColor)
text = event.title
val startDateTime = Formatter.getDateTimeFromTS(event.startTS)

View File

@ -13,16 +13,16 @@ import com.simplemobiletools.calendar.adapters.MyWeekPagerAdapter
import com.simplemobiletools.calendar.extensions.config
import com.simplemobiletools.calendar.extensions.seconds
import com.simplemobiletools.calendar.helpers.Formatter
import com.simplemobiletools.calendar.helpers.WEEK_SECONDS
import com.simplemobiletools.calendar.helpers.WEEK_START_DATE_TIME
import com.simplemobiletools.calendar.interfaces.WeekFragmentListener
import com.simplemobiletools.calendar.views.MyScrollView
import com.simplemobiletools.commons.helpers.WEEK_SECONDS
import kotlinx.android.synthetic.main.fragment_week_holder.*
import kotlinx.android.synthetic.main.fragment_week_holder.view.*
import org.joda.time.DateTime
class WeekFragmentsHolder : MyFragmentHolder(), WeekFragmentListener {
private val PREFILLED_WEEKS = 61
private val PREFILLED_WEEKS = 151
private var weekHolder: ViewGroup? = null
private var defaultWeeklyPage = 0

View File

@ -16,7 +16,7 @@ import kotlinx.android.synthetic.main.fragment_years_holder.view.*
import org.joda.time.DateTime
class YearFragmentsHolder : MyFragmentHolder() {
private val PREFILLED_YEARS = 31
private val PREFILLED_YEARS = 61
private var viewPager: MyViewPager? = null
private var defaultYearlyPage = 0

View File

@ -22,7 +22,8 @@ import kotlin.collections.ArrayList
class CalDAVHandler(val context: Context) {
fun refreshCalendars(activity: SimpleActivity? = null, callback: () -> Unit) {
for (calendar in getCalDAVCalendars(activity, context.config.caldavSyncedCalendarIDs)) {
val calDAVCalendars = getCalDAVCalendars(activity, context.config.caldavSyncedCalendarIDs)
for (calendar in calDAVCalendars) {
val localEventType = context.dbHelper.getEventTypeWithCalDAVCalendarId(calendar.id) ?: continue
localEventType.apply {
title = calendar.displayName
@ -185,8 +186,9 @@ class CalDAVHandler(val context: Context) {
cursor?.close()
}
val sortedColors = ArrayList<Int>(colors.size())
var sortedColors = ArrayList<Int>(colors.size())
(0 until colors.size()).mapTo(sortedColors) { colors[it] }
sortedColors = sortedColors.distinct() as ArrayList<Int>
return sortedColors
}
@ -358,11 +360,17 @@ class CalDAVHandler(val context: Context) {
put(CalendarContract.Events.DESCRIPTION, event.description)
put(CalendarContract.Events.DTSTART, event.startTS * 1000L)
put(CalendarContract.Events.ALL_DAY, if (event.getIsAllDay()) 1 else 0)
put(CalendarContract.Events.RRULE, Parser().getRepeatCode(event))
put(CalendarContract.Events.EVENT_TIMEZONE, TimeZone.getDefault().toString())
put(CalendarContract.Events.EVENT_LOCATION, event.location)
put(CalendarContract.Events.STATUS, CalendarContract.Events.STATUS_CONFIRMED)
val repeatRule = Parser().getRepeatCode(event)
if (repeatRule.isEmpty()) {
putNull(CalendarContract.Events.RRULE)
} else {
put(CalendarContract.Events.RRULE, repeatRule)
}
if (event.getIsAllDay() && event.endTS > event.startTS)
event.endTS += DAY
@ -416,8 +424,8 @@ class CalDAVHandler(val context: Context) {
private fun fillEventRepeatExceptionValues(event: Event, occurrenceTS: Int): ContentValues {
return ContentValues().apply {
put(CalendarContract.Events.CALENDAR_ID, event.getCalDAVCalendarId())
put(CalendarContract.Events.DTSTART, 0)
put(CalendarContract.Events.DTEND, 0)
put(CalendarContract.Events.DTSTART, occurrenceTS)
put(CalendarContract.Events.DTEND, occurrenceTS + (event.endTS - event.startTS))
put(CalendarContract.Events.ORIGINAL_ID, event.getCalDAVEventId())
put(CalendarContract.Events.EVENT_TIMEZONE, TimeZone.getDefault().toString())
put(CalendarContract.Events.ORIGINAL_INSTANCE_TIME, occurrenceTS * 1000L)

View File

@ -7,6 +7,7 @@ import com.simplemobiletools.commons.extensions.getDefaultAlarmTitle
import com.simplemobiletools.commons.extensions.getDefaultAlarmUri
import com.simplemobiletools.commons.helpers.ALARM_SOUND_TYPE_NOTIFICATION
import com.simplemobiletools.commons.helpers.BaseConfig
import com.simplemobiletools.commons.helpers.DAY_MINUTES
import java.util.*
class Config(context: Context) : BaseConfig(context) {
@ -55,7 +56,7 @@ class Config(context: Context) : BaseConfig(context) {
set(defaultReminderMinutes3) = prefs.edit().putInt(REMINDER_MINUTES_3, defaultReminderMinutes3).apply()
var displayPastEvents: Int
get() = prefs.getInt(DISPLAY_PAST_EVENTS, 0)
get() = prefs.getInt(DISPLAY_PAST_EVENTS, DAY_MINUTES)
set(displayPastEvents) = prefs.edit().putInt(DISPLAY_PAST_EVENTS, displayPastEvents).apply()
var displayEventTypes: Set<String>
@ -77,10 +78,14 @@ class Config(context: Context) : BaseConfig(context) {
get() = prefs.getString(CALDAV_SYNCED_CALENDAR_IDS, "")
set(calendarIDs) = prefs.edit().putString(CALDAV_SYNCED_CALENDAR_IDS, calendarIDs).apply()
var lastUsedCaldavCalendar: Int
var lastUsedCaldavCalendarId: Int
get() = prefs.getInt(LAST_USED_CALDAV_CALENDAR, getSyncedCalendarIdsAsList().first().toInt())
set(calendarId) = prefs.edit().putInt(LAST_USED_CALDAV_CALENDAR, calendarId).apply()
var lastUsedLocalEventTypeId: Int
get() = prefs.getInt(LAST_USED_LOCAL_EVENT_TYPE_ID, DBHelper.REGULAR_EVENT_TYPE_ID)
set(lastUsedLocalEventTypeId) = prefs.edit().putInt(LAST_USED_LOCAL_EVENT_TYPE_ID, lastUsedLocalEventTypeId).apply()
var replaceDescription: Boolean
get() = prefs.getBoolean(REPLACE_DESCRIPTION, false)
set(replaceDescription) = prefs.edit().putBoolean(REPLACE_DESCRIPTION, replaceDescription).apply()
@ -89,6 +94,14 @@ class Config(context: Context) : BaseConfig(context) {
get() = prefs.getBoolean(SHOW_GRID, false)
set(showGrid) = prefs.edit().putBoolean(SHOW_GRID, showGrid).apply()
var loopReminders: Boolean
get() = prefs.getBoolean(LOOP_REMINDERS, false)
set(loopReminders) = prefs.edit().putBoolean(LOOP_REMINDERS, loopReminders).apply()
var dimPastEvents: Boolean
get() = prefs.getBoolean(DIM_PAST_EVENTS, true)
set(dimPastEvents) = prefs.edit().putBoolean(DIM_PAST_EVENTS, dimPastEvents).apply()
fun getSyncedCalendarIdsAsList() = caldavSyncedCalendarIDs.split(",").filter { it.trim().isNotEmpty() } as ArrayList<String>
fun addDisplayEventType(type: String) {

View File

@ -7,6 +7,7 @@ const val STORED_LOCALLY_ONLY = 0
const val DAY_CODE = "day_code"
const val YEAR_LABEL = "year"
const val EVENT_ID = "event_id"
const val IS_DUPLICATE_INTENT = "is_duplicate_intent"
const val EVENT_OCCURRENCE_TS = "event_occurrence_ts"
const val NEW_EVENT_START_TS = "new_event_start_ts"
const val WEEK_START_TIMESTAMP = "week_start_timestamp"
@ -28,10 +29,6 @@ const val WEEK = 604800
const val MONTH = 2592001 // exact value not taken into account, Joda is used for adding months and years
const val YEAR = 31536000
const val DAY_MINUTES = 24 * 60
const val DAY_SECONDS = 24 * 60 * 60
const val WEEK_SECONDS = 7 * DAY_SECONDS
// Shared Preferences
const val WEEK_NUMBERS = "week_numbers"
const val START_WEEKLY_AT = "start_weekly_at"
@ -48,15 +45,19 @@ const val FONT_SIZE = "font_size"
const val CALDAV_SYNC = "caldav_sync"
const val CALDAV_SYNCED_CALENDAR_IDS = "caldav_synced_calendar_ids"
const val LAST_USED_CALDAV_CALENDAR = "last_used_caldav_calendar"
const val LAST_USED_LOCAL_EVENT_TYPE_ID = "last_used_local_event_type_id"
const val DISPLAY_PAST_EVENTS = "display_past_events"
const val REPLACE_DESCRIPTION = "replace_description"
const val SHOW_GRID = "show_grid"
const val IS_CUSTOMIZING_COLORS = "is_customizing_colors"
const val LOOP_REMINDERS = "loop_reminders"
const val DIM_PAST_EVENTS = "dim_past_events"
// repeat_rule for monthly repetition
const val REPEAT_MONTH_SAME_DAY = 1 // ie 25th every month
const val REPEAT_MONTH_ORDER_WEEKDAY_USE_LAST = 2 // ie every xth sunday. 4th if a month has 4 sundays, 5th if 5
const val REPEAT_MONTH_LAST_DAY = 3 // ie every last day of the month
const val REPEAT_MONTH_ORDER_WEEKDAY = 4 // ie every 4th sunday, even if a month has 4 sundays only (will stay 4th even at months with 5)
const val REPEAT_SAME_DAY = 1 // i.e. 25th every month, or 3rd june (if yearly repetition)
const val REPEAT_ORDER_WEEKDAY_USE_LAST = 2 // i.e. every last sunday. 4th if a month has 4 sundays, 5th if 5 (or last sunday in june, if yearly)
const val REPEAT_LAST_DAY = 3 // i.e. every last day of the month
const val REPEAT_ORDER_WEEKDAY = 4 // i.e. every 4th sunday, even if a month has 4 sundays only (will stay 4th even at months with 5)
// special event flags
const val FLAG_ALL_DAY = 1
@ -85,7 +86,7 @@ const val STATUS = "STATUS:"
const val EXDATE = "EXDATE"
const val BYDAY = "BYDAY"
const val BYMONTHDAY = "BYMONTHDAY"
const val LOCATION = "LOCATION:"
const val LOCATION = "LOCATION"
// this tag isn't a standard ICS tag, but there's no official way of adding a category color in an ics file
const val CATEGORY_COLOR = "CATEGORY_COLOR:"
@ -121,3 +122,5 @@ const val SOURCE_SIMPLE_CALENDAR = "simple-calendar"
const val SOURCE_IMPORTED_ICS = "imported-ics"
const val SOURCE_CONTACT_BIRTHDAY = "contact-birthday"
const val SOURCE_CONTACT_ANNIVERSARY = "contact-anniversary"
fun getNowSeconds() = (System.currentTimeMillis() / 1000).toInt()

View File

@ -243,7 +243,7 @@ class DBHelper private constructor(val context: Context) : SQLiteOpenHelper(cont
}
context.scheduleNextEventReminder(event, this)
if (addToCalDAV && event.source != SOURCE_SIMPLE_CALENDAR && context.config.caldavSync) {
if (addToCalDAV && event.source != SOURCE_SIMPLE_CALENDAR && event.source != SOURCE_IMPORTED_ICS && context.config.caldavSync) {
CalDAVHandler(context).insertCalDAVEvent(event)
}
}
@ -652,17 +652,21 @@ class DBHelper private constructor(val context: Context) : SQLiteOpenHelper(cont
val selection = "$MAIN_TABLE_NAME.$COL_TITLE LIKE ? OR $MAIN_TABLE_NAME.$COL_LOCATION LIKE ? OR $MAIN_TABLE_NAME.$COL_DESCRIPTION LIKE ?"
val selectionArgs = arrayOf(searchQuery, searchQuery, searchQuery)
val cursor = getEventsCursor(selection, selectionArgs)
callback(text, fillEvents(cursor))
val events = fillEvents(cursor)
val displayEventTypes = context.config.displayEventTypes
val filteredEvents = events.filter { displayEventTypes.contains(it.eventType.toString()) }
callback(text, filteredEvents)
}.start()
}
fun getEvents(fromTS: Int, toTS: Int, eventId: Int = -1, callback: (events: MutableList<Event>) -> Unit) {
fun getEvents(fromTS: Int, toTS: Int, eventId: Int = -1, callback: (events: ArrayList<Event>) -> Unit) {
Thread {
getEventsInBackground(fromTS, toTS, eventId, callback)
}.start()
}
fun getEventsInBackground(fromTS: Int, toTS: Int, eventId: Int = -1, callback: (events: MutableList<Event>) -> Unit) {
fun getEventsInBackground(fromTS: Int, toTS: Int, eventId: Int = -1, callback: (events: ArrayList<Event>) -> Unit) {
val events = ArrayList<Event>()
var selection = "$COL_START_TS <= ? AND $COL_END_TS >= ? AND $COL_REPEAT_INTERVAL IS NULL AND $COL_START_TS != 0"
@ -674,13 +678,13 @@ class DBHelper private constructor(val context: Context) : SQLiteOpenHelper(cont
events.addAll(getRepeatableEventsFor(fromTS, toTS, eventId))
events.addAll(getAllDayEvents(fromTS, toTS, eventId))
events.addAll(getAllDayEvents(fromTS, eventId))
val filtered = events.distinct().filterNot { it.ignoreEventOccurrences.contains(Formatter.getDayCodeFromTS(it.startTS).toInt()) } as MutableList<Event>
val filtered = events.distinct().filterNot { it.ignoreEventOccurrences.contains(Formatter.getDayCodeFromTS(it.startTS).toInt()) } as ArrayList<Event>
callback(filtered)
}
private fun getRepeatableEventsFor(fromTS: Int, toTS: Int, eventId: Int = -1): List<Event> {
fun getRepeatableEventsFor(fromTS: Int, toTS: Int, eventId: Int = -1): List<Event> {
val newEvents = ArrayList<Event>()
// get repeatable events
@ -709,11 +713,11 @@ class DBHelper private constructor(val context: Context) : SQLiteOpenHelper(cont
if (event.repeatInterval.isXWeeklyRepetition()) {
if (event.startTS.isTsOnProperDay(event)) {
if (isOnProperWeek(event, startTimes)) {
events.add(event.copy())
events.add(event.copy(isPastEvent = getIsPastEvent(event)))
}
}
} else {
events.add(event.copy())
events.add(event.copy(isPastEvent = getIsPastEvent(event)))
}
}
@ -721,14 +725,14 @@ class DBHelper private constructor(val context: Context) : SQLiteOpenHelper(cont
if (event.repeatInterval.isXWeeklyRepetition()) {
if (event.endTS >= toTS && event.startTS.isTsOnProperDay(event)) {
if (isOnProperWeek(event, startTimes)) {
events.add(event.copy())
events.add(event.copy(isPastEvent = getIsPastEvent(event)))
}
}
} else {
val dayCode = Formatter.getDayCodeFromTS(fromTS)
val endDayCode = Formatter.getDayCodeFromTS(event.endTS)
if (dayCode == endDayCode) {
events.add(event.copy())
events.add(event.copy(isPastEvent = getIsPastEvent(event)))
}
}
}
@ -745,7 +749,7 @@ class DBHelper private constructor(val context: Context) : SQLiteOpenHelper(cont
if (event.startTS.isTsOnProperDay(event)) {
if (isOnProperWeek(event, startTimes)) {
if (event.endTS >= fromTS) {
events.add(event.copy())
events.add(event.copy(isPastEvent = getIsPastEvent(event)))
}
event.repeatLimit++
}
@ -757,7 +761,7 @@ class DBHelper private constructor(val context: Context) : SQLiteOpenHelper(cont
val dayCode = Formatter.getDayCodeFromTS(fromTS)
val endDayCode = Formatter.getDayCodeFromTS(event.endTS)
if (dayCode == endDayCode) {
events.add(event.copy())
events.add(event.copy(isPastEvent = getIsPastEvent(event)))
}
}
event.repeatLimit++
@ -767,7 +771,7 @@ class DBHelper private constructor(val context: Context) : SQLiteOpenHelper(cont
return events
}
private fun getAllDayEvents(fromTS: Int, toTS: Int, eventId: Int = -1): List<Event> {
private fun getAllDayEvents(fromTS: Int, eventId: Int = -1): List<Event> {
val events = ArrayList<Event>()
var selection = "($COL_FLAGS & $FLAG_ALL_DAY) != 0"
if (eventId != -1)
@ -788,7 +792,7 @@ class DBHelper private constructor(val context: Context) : SQLiteOpenHelper(cont
fun getRunningEvents(): List<Event> {
val events = ArrayList<Event>()
val ts = context.getNowSeconds()
val ts = getNowSeconds()
val selection = "$COL_START_TS <= ? AND $COL_END_TS >= ? AND $COL_REPEAT_INTERVAL IS 0 AND $COL_START_TS != 0"
val selectionArgs = arrayOf(ts.toString(), ts.toString())
@ -829,7 +833,7 @@ class DBHelper private constructor(val context: Context) : SQLiteOpenHelper(cont
}
fun getEventsToExport(includePast: Boolean): ArrayList<Event> {
val currTime = context.getNowSeconds().toString()
val currTime = getNowSeconds().toString()
var events = ArrayList<Event>()
// non repeating events
@ -875,7 +879,7 @@ class DBHelper private constructor(val context: Context) : SQLiteOpenHelper(cont
private fun fillEvents(cursor: Cursor?): List<Event> {
val eventTypeColors = SparseIntArray()
fetchEventTypes().forEach {
getEventTypesSync().forEach {
eventTypeColors.put(it.id, it.color)
}
@ -911,12 +915,15 @@ class DBHelper private constructor(val context: Context) : SQLiteOpenHelper(cont
}
if (repeatInterval > 0 && repeatInterval % MONTH == 0 && repeatRule == 0) {
repeatRule = REPEAT_MONTH_SAME_DAY
repeatRule = REPEAT_SAME_DAY
}
val isPastEvent = endTS < getNowSeconds()
val event = Event(id, startTS, endTS, title, description, reminder1Minutes, reminder2Minutes, reminder3Minutes,
repeatInterval, importId, flags, repeatLimit, repeatRule, eventType, ignoreEventOccurrences, offset, isDstIncluded,
0, lastUpdated, source, color, location)
0, lastUpdated, source, color, location, isPastEvent)
events.add(event)
} while (cursor.moveToNext())
}
@ -926,11 +933,11 @@ class DBHelper private constructor(val context: Context) : SQLiteOpenHelper(cont
fun getEventTypes(callback: (types: ArrayList<EventType>) -> Unit) {
Thread {
callback(fetchEventTypes())
callback(getEventTypesSync())
}.start()
}
fun fetchEventTypes(): ArrayList<EventType> {
fun getEventTypesSync(): ArrayList<EventType> {
val eventTypes = ArrayList<EventType>(4)
val cols = arrayOf(COL_TYPE_ID, COL_TYPE_TITLE, COL_TYPE_COLOR, COL_TYPE_CALDAV_CALENDAR_ID, COL_TYPE_CALDAV_DISPLAY_NAME, COL_TYPE_CALDAV_EMAIL)
var cursor: Cursor? = null
@ -951,6 +958,7 @@ class DBHelper private constructor(val context: Context) : SQLiteOpenHelper(cont
} finally {
cursor?.close()
}
return eventTypes
}
@ -1025,7 +1033,7 @@ class DBHelper private constructor(val context: Context) : SQLiteOpenHelper(cont
val start = cursor.getIntValue(COL_REPEAT_START)
var rule = Math.pow(2.0, (Formatter.getDateTimeFromTS(start).dayOfWeek - 1).toDouble()).toInt()
if (interval == MONTH) {
rule = REPEAT_MONTH_SAME_DAY
rule = REPEAT_SAME_DAY
}
val values = ContentValues()
@ -1039,4 +1047,6 @@ class DBHelper private constructor(val context: Context) : SQLiteOpenHelper(cont
cursor?.close()
}
}
private fun getIsPastEvent(event: Event) = event.endTS < getNowSeconds()
}

View File

@ -3,7 +3,6 @@ package com.simplemobiletools.calendar.helpers
import android.content.Context
import com.simplemobiletools.calendar.R
import com.simplemobiletools.calendar.extensions.config
import com.simplemobiletools.calendar.extensions.getNowSeconds
import com.simplemobiletools.calendar.extensions.seconds
import org.joda.time.DateTime
import org.joda.time.DateTimeZone
@ -11,17 +10,17 @@ import org.joda.time.LocalDate
import org.joda.time.format.DateTimeFormat
object Formatter {
val DAYCODE_PATTERN = "YYYYMMdd"
val YEAR_PATTERN = "YYYY"
val TIME_PATTERN = "HHmmss"
private val DAY_PATTERN = "d"
private val DAY_OF_WEEK_PATTERN = "EEE"
private val LONGEST_PATTERN = "MMMM dd YYYY (EEEE)"
private val PATTERN_TIME_12 = "hh:mm a"
private val PATTERN_TIME_24 = "HH:mm"
const val DAYCODE_PATTERN = "YYYYMMdd"
const val YEAR_PATTERN = "YYYY"
const val TIME_PATTERN = "HHmmss"
private const val DAY_PATTERN = "d"
private const val DAY_OF_WEEK_PATTERN = "EEE"
private const val LONGEST_PATTERN = "MMMM dd YYYY (EEEE)"
private const val PATTERN_TIME_12 = "hh:mm a"
private const val PATTERN_TIME_24 = "HH:mm"
private val PATTERN_HOURS_12 = "h a"
private val PATTERN_HOURS_24 = "HH"
private const val PATTERN_HOURS_12 = "h a"
private const val PATTERN_HOURS_24 = "HH"
fun getDateFromCode(context: Context, dayCode: String, shortMonth: Boolean = false): String {
val dateTime = getDateTimeFromCode(dayCode)
@ -59,7 +58,7 @@ object Formatter {
return "$month $day $year"
}
fun getTodayCode(context: Context) = Formatter.getDayCodeFromTS(context.getNowSeconds())
fun getTodayCode(context: Context) = Formatter.getDayCodeFromTS(getNowSeconds())
fun getHours(context: Context, dateTime: DateTime) = dateTime.toString(getHourPattern(context))

View File

@ -28,7 +28,7 @@ class IcsImporter(val activity: SimpleActivity) {
private var curRepeatInterval = 0
private var curRepeatLimit = 0
private var curRepeatRule = 0
private var curEventType = DBHelper.REGULAR_EVENT_TYPE_ID
private var curEventTypeId = DBHelper.REGULAR_EVENT_TYPE_ID
private var curLastModified = 0L
private var curLocation = ""
private var curCategoryColor = -2
@ -40,8 +40,9 @@ class IcsImporter(val activity: SimpleActivity) {
private var eventsImported = 0
private var eventsFailed = 0
fun importEvents(path: String, defaultEventType: Int, calDAVCalendarId: Int): ImportResult {
fun importEvents(path: String, defaultEventTypeId: Int, calDAVCalendarId: Int, overrideFileEventTypes: Boolean): ImportResult {
try {
val eventTypes = activity.dbHelper.getEventTypesSync()
val existingEvents = activity.dbHelper.getEventsWithImportIds()
val eventsToInsert = ArrayList<Event>()
var prevLine = ""
@ -74,7 +75,7 @@ class IcsImporter(val activity: SimpleActivity) {
if (line == BEGIN_EVENT) {
resetValues()
curEventType = defaultEventType
curEventTypeId = defaultEventTypeId
} else if (line.startsWith(DTSTART)) {
curStart = getTimestamp(line.substring(DTSTART.length))
} else if (line.startsWith(DTEND)) {
@ -84,9 +85,9 @@ class IcsImporter(val activity: SimpleActivity) {
curEnd = curStart + Parser().parseDurationSeconds(duration)
} else if (line.startsWith(SUMMARY) && !isNotificationDescription) {
curTitle = line.substring(SUMMARY.length)
curTitle = getTitle(curTitle).replace("\\n", "\n")
curTitle = getTitle(curTitle).replace("\\n", "\n").replace("\\,", ",")
} else if (line.startsWith(DESCRIPTION) && !isNotificationDescription) {
curDescription = line.substring(DESCRIPTION.length).replace("\\n", "\n")
curDescription = line.substring(DESCRIPTION.length).replace("\\n", "\n").replace("\\,", ",")
isDescription = true
} else if (line.startsWith(UID)) {
curImportId = line.substring(UID.length).trim()
@ -105,7 +106,7 @@ class IcsImporter(val activity: SimpleActivity) {
if (color.trimStart('-').areDigitsOnly()) {
curCategoryColor = Integer.parseInt(color)
}
} else if (line.startsWith(CATEGORIES)) {
} else if (line.startsWith(CATEGORIES) && !overrideFileEventTypes) {
val categories = line.substring(CATEGORIES.length)
tryAddCategories(categories, activity)
} else if (line.startsWith(LAST_MODIFIED)) {
@ -118,7 +119,7 @@ class IcsImporter(val activity: SimpleActivity) {
curRepeatExceptions.add(getTimestamp(value))
} else if (line.startsWith(LOCATION)) {
curLocation = line.substring(LOCATION.length)
curLocation = getLocation(line.substring(LOCATION.length).replace("\\,", ","))
} else if (line == END_ALARM) {
if (isProperReminderAction && curReminderTriggerMinutes != -1) {
curReminderMinutes.add(curReminderTriggerMinutes)
@ -137,10 +138,11 @@ class IcsImporter(val activity: SimpleActivity) {
continue
}
val source = if (calDAVCalendarId == 0) SOURCE_IMPORTED_ICS else "$CALDAV-$calDAVCalendarId"
val eventType = eventTypes.firstOrNull { it.id == curEventTypeId }
val source = if (calDAVCalendarId == 0 || eventType?.isSyncedEventType() == false) SOURCE_IMPORTED_ICS else "$CALDAV-$calDAVCalendarId"
val event = Event(0, curStart, curEnd, curTitle, curDescription, curReminderMinutes.getOrElse(0, { -1 }),
curReminderMinutes.getOrElse(1, { -1 }), curReminderMinutes.getOrElse(2, { -1 }), curRepeatInterval,
curImportId, curFlags, curRepeatLimit, curRepeatRule, curEventType, lastUpdated = curLastModified,
curImportId, curFlags, curRepeatLimit, curRepeatRule, curEventTypeId, lastUpdated = curLastModified,
source = source, location = curLocation)
if (event.getIsAllDay() && curEnd > curStart) {
@ -201,6 +203,14 @@ class IcsImporter(val activity: SimpleActivity) {
}
}
private fun getLocation(fullString: String): String {
return if (fullString.startsWith(":")) {
fullString.trimStart(':')
} else {
fullString.substringAfter(':').trim()
}
}
private fun tryAddCategories(categories: String, context: Context) {
val eventTypeTitle = if (categories.contains(",")) {
categories.split(",")[0]
@ -209,7 +219,7 @@ class IcsImporter(val activity: SimpleActivity) {
}
val eventId = context.dbHelper.getEventTypeIdWithTitle(eventTypeTitle)
curEventType = if (eventId == -1) {
curEventTypeId = if (eventId == -1) {
val newTypeColor = if (curCategoryColor == -2) context.resources.getColor(R.color.color_primary) else curCategoryColor
val eventType = EventType(0, eventTypeTitle, newTypeColor)
context.dbHelper.insertEventType(eventType)
@ -238,7 +248,7 @@ class IcsImporter(val activity: SimpleActivity) {
curRepeatInterval = 0
curRepeatLimit = 0
curRepeatRule = 0
curEventType = DBHelper.REGULAR_EVENT_TYPE_ID
curEventTypeId = DBHelper.REGULAR_EVENT_TYPE_ID
curLastModified = 0L
curCategoryColor = -2
curLocation = ""

View File

@ -11,7 +11,6 @@ import android.widget.RemoteViews
import com.simplemobiletools.calendar.R
import com.simplemobiletools.calendar.activities.SplashActivity
import com.simplemobiletools.calendar.extensions.config
import com.simplemobiletools.calendar.extensions.getNowSeconds
import com.simplemobiletools.calendar.extensions.launchNewEventIntent
import com.simplemobiletools.calendar.services.WidgetService
import com.simplemobiletools.commons.extensions.getColoredBitmap
@ -43,7 +42,7 @@ class MyWidgetListProvider : AppWidgetProvider() {
setTextSize(R.id.widget_event_list_today, fontSize)
}
val todayText = Formatter.getLongestDate(context.getNowSeconds())
val todayText = Formatter.getLongestDate(getNowSeconds())
views.setText(R.id.widget_event_list_today, todayText)
views.setImageViewBitmap(R.id.widget_event_new_event, context.resources.getColoredBitmap(R.drawable.ic_plus, textColor))

View File

@ -84,6 +84,7 @@ class MyWidgetMonthlyProvider : AppWidgetProvider() {
private fun updateDays(context: Context, views: RemoteViews, days: List<DayMonthly>) {
val displayWeekNumbers = context.config.showWeekNumbers
val textColor = context.config.widgetTextColor
val dimPastEvents = context.config.dimPastEvents
val smallerFontSize = context.config.getFontSize() - 3f
val res = context.resources
val len = days.size
@ -117,7 +118,7 @@ class MyWidgetMonthlyProvider : AppWidgetProvider() {
var backgroundColor = it.color
var eventTextColor = backgroundColor.getContrastColor()
if (!day.isThisMonth) {
if (!day.isThisMonth || (dimPastEvents && it.isPastEvent)) {
eventTextColor = eventTextColor.adjustAlpha(0.25f)
backgroundColor = backgroundColor.adjustAlpha(0.25f)
}

View File

@ -30,7 +30,7 @@ class Parser {
val start = Formatter.getDateTimeFromTS(startTS)
repeatRule = Math.pow(2.0, (start.dayOfWeek - 1).toDouble()).toInt()
} else if (value == MONTHLY) {
repeatRule = REPEAT_MONTH_SAME_DAY
repeatRule = REPEAT_SAME_DAY
}
} else if (key == COUNT) {
repeatLimit = -value.toInt()
@ -42,10 +42,10 @@ class Parser {
if (repeatInterval.isXWeeklyRepetition()) {
repeatRule = handleRepeatRule(value)
} else if (repeatInterval.isXMonthlyRepetition()) {
repeatRule = if (value.startsWith("-1")) REPEAT_MONTH_ORDER_WEEKDAY_USE_LAST else REPEAT_MONTH_ORDER_WEEKDAY
repeatRule = if (value.startsWith("-1")) REPEAT_ORDER_WEEKDAY_USE_LAST else REPEAT_ORDER_WEEKDAY
}
} else if (key == BYMONTHDAY && value.toInt() == -1) {
repeatRule = REPEAT_MONTH_LAST_DAY
repeatRule = REPEAT_LAST_DAY
}
}
return RepeatRule(repeatInterval, repeatRule, repeatLimit)
@ -133,8 +133,8 @@ class Parser {
";$BYDAY=$days"
}
event.repeatInterval.isXMonthlyRepetition() -> when (event.repeatRule) {
REPEAT_MONTH_LAST_DAY -> ";$BYMONTHDAY=-1"
REPEAT_MONTH_ORDER_WEEKDAY_USE_LAST, REPEAT_MONTH_ORDER_WEEKDAY -> {
REPEAT_LAST_DAY -> ";$BYMONTHDAY=-1"
REPEAT_ORDER_WEEKDAY_USE_LAST, REPEAT_ORDER_WEEKDAY -> {
val start = Formatter.getDateTimeFromTS(event.startTS)
val dayOfMonth = start.dayOfMonth
val isLastWeekday = start.monthOfYear != start.plusDays(7).monthOfYear

View File

@ -4,6 +4,7 @@ import android.content.Context
import com.simplemobiletools.calendar.extensions.dbHelper
import com.simplemobiletools.calendar.interfaces.WeeklyCalendar
import com.simplemobiletools.calendar.models.Event
import com.simplemobiletools.commons.helpers.WEEK_SECONDS
import java.util.*
class WeeklyCalendarImpl(val mCallback: WeeklyCalendar, val mContext: Context) {

View File

@ -2,6 +2,4 @@ package com.simplemobiletools.calendar.models
data class DayMonthly(val value: Int, val isThisMonth: Boolean, val isToday: Boolean, val code: String, val weekOfYear: Int, var dayEvents: ArrayList<Event>,
var indexOnMonthView: Int) {
fun hasEvent() = dayEvents.isNotEmpty()
}

View File

@ -3,6 +3,7 @@ package com.simplemobiletools.calendar.models
import com.simplemobiletools.calendar.extensions.seconds
import com.simplemobiletools.calendar.helpers.*
import com.simplemobiletools.calendar.helpers.Formatter
import com.simplemobiletools.commons.helpers.DAY_SECONDS
import org.joda.time.DateTime
import java.io.Serializable
import java.util.*
@ -12,38 +13,47 @@ data class Event(var id: Int = 0, var startTS: Int = 0, var endTS: Int = 0, var
var importId: String = "", var flags: Int = 0, var repeatLimit: Int = 0, var repeatRule: Int = 0,
var eventType: Int = DBHelper.REGULAR_EVENT_TYPE_ID, var ignoreEventOccurrences: ArrayList<Int> = ArrayList(),
var offset: String = "", var isDstIncluded: Boolean = false, var parentId: Int = 0, var lastUpdated: Long = 0L,
var source: String = SOURCE_SIMPLE_CALENDAR, var color: Int = 0, var location: String = "") : Serializable {
var source: String = SOURCE_SIMPLE_CALENDAR, var color: Int = 0, var location: String = "", var isPastEvent: Boolean = false)
: Serializable {
companion object {
private val serialVersionUID = -32456795132345616L
}
fun addIntervalTime(original: Event) {
val currStart = Formatter.getDateTimeFromTS(startTS)
val newStart: DateTime
newStart = when (repeatInterval) {
DAY -> currStart.plusDays(1)
when (repeatInterval) {
DAY -> {
startTS += DAY_SECONDS
endTS += DAY_SECONDS
}
else -> {
when {
val currStart = Formatter.getDateTimeFromTS(startTS)
val newStart = when {
repeatInterval % YEAR == 0 -> currStart.plusYears(repeatInterval / YEAR)
repeatInterval % MONTH == 0 -> when (repeatRule) {
REPEAT_MONTH_SAME_DAY -> addMonthsWithSameDay(currStart, original)
REPEAT_MONTH_ORDER_WEEKDAY_USE_LAST -> addXthDayInterval(currStart, original, true)
REPEAT_MONTH_ORDER_WEEKDAY -> addXthDayInterval(currStart, original, false)
REPEAT_SAME_DAY -> addMonthsWithSameDay(currStart, original)
REPEAT_ORDER_WEEKDAY_USE_LAST -> addXthDayInterval(currStart, original, true)
REPEAT_ORDER_WEEKDAY -> addXthDayInterval(currStart, original, false)
else -> currStart.plusMonths(repeatInterval / MONTH).dayOfMonth().withMaximumValue()
}
repeatInterval % WEEK == 0 -> {
// step through weekly repetition by days too, as events can trigger multiple times a week
currStart.plusDays(1)
// step through weekly repetition by days, as events can trigger multiple times a week
startTS += DAY_SECONDS
endTS += DAY_SECONDS
return
}
else -> {
startTS += repeatInterval
endTS += repeatInterval
return
}
else -> currStart.plusSeconds(repeatInterval)
}
val newStartTS = newStart.seconds()
val newEndTS = newStartTS + (endTS - startTS)
startTS = newStartTS
endTS = newEndTS
}
}
val newStartTS = newStart.seconds()
val newEndTS = newStartTS + (endTS - startTS)
startTS = newStartTS
endTS = newEndTS
}
// if an event should happen on 31st with Same Day monthly repetition, dont show it at all at months with 30 or less days

View File

@ -2,4 +2,6 @@ package com.simplemobiletools.calendar.models
data class EventType(var id: Int = 0, var title: String, var color: Int, var caldavCalendarId: Int = 0, var caldavDisplayName: String = "", var caldavEmail: String = "") {
fun getDisplayTitle() = if (caldavCalendarId == 0) title else "$caldavDisplayName ($caldavEmail)"
fun isSyncedEventType() = caldavCalendarId != 0
}

View File

@ -1,4 +1,4 @@
package com.simplemobiletools.calendar.models
class ListEvent(var id: Int = 0, var startTS: Int = 0, var endTS: Int = 0, var title: String = "", var description: String = "",
var isAllDay: Boolean, var color: Int, var location: String = "") : ListItem()
data class ListEvent(var id: Int = 0, var startTS: Int = 0, var endTS: Int = 0, var title: String = "", var description: String = "",
var isAllDay: Boolean, var color: Int, var location: String = "", var isPastEvent: Boolean = false) : ListItem()

View File

@ -1,3 +1,3 @@
package com.simplemobiletools.calendar.models
data class ListSection(val title: String, val code: String, val isToday: Boolean = false) : ListItem()
data class ListSection(val title: String, val code: String, val isToday: Boolean, val isPastSection: Boolean) : ListItem()

View File

@ -1,4 +1,4 @@
package com.simplemobiletools.calendar.models
data class MonthViewEvent(val id: Int, val title: String, val startTS: Int, val color: Int, val startDayIndex: Int, val daysCnt: Int, val originalStartDayIndex: Int,
val isAllDay: Boolean)
val isAllDay: Boolean, val isPastEvent: Boolean)

View File

@ -3,6 +3,7 @@ package com.simplemobiletools.calendar.receivers
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import com.simplemobiletools.calendar.extensions.dbHelper
import com.simplemobiletools.calendar.extensions.notifyRunningEvents
import com.simplemobiletools.calendar.extensions.recheckCalDAVCalendars
import com.simplemobiletools.calendar.extensions.scheduleAllEvents
@ -10,6 +11,9 @@ import com.simplemobiletools.calendar.extensions.scheduleAllEvents
class BootCompletedReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
// try just getting a reference to the db so it updates in time
context.dbHelper
Thread {
context.apply {
scheduleAllEvents()

View File

@ -43,6 +43,7 @@ class MonthView(context: Context, attrs: AttributeSet, defStyle: Int) : View(con
private var maxEventsPerDay = 0
private var horizontalOffset = 0
private var showWeekNumbers = false
private var dimPastEvents = true
private var allEvents = ArrayList<MonthViewEvent>()
private var bgRectF = RectF()
private var dayLetters = ArrayList<String>()
@ -55,6 +56,7 @@ class MonthView(context: Context, attrs: AttributeSet, defStyle: Int) : View(con
primaryColor = context.getAdjustedPrimaryColor()
textColor = context.config.textColor
showWeekNumbers = context.config.showWeekNumbers
dimPastEvents = context.config.dimPastEvents
smallPadding = resources.displayMetrics.density.toInt()
val normalTextSize = resources.getDimensionPixelSize(R.dimen.normal_text_size)
@ -103,7 +105,7 @@ class MonthView(context: Context, attrs: AttributeSet, defStyle: Int) : View(con
val daysCnt = getEventLastingDaysCount(event)
if (lastEvent == null || lastEvent.startDayIndex + daysCnt <= day.indexOnMonthView) {
val monthViewEvent = MonthViewEvent(event.id, event.title, event.startTS, event.color, day.indexOnMonthView,
daysCnt, day.indexOnMonthView, event.getIsAllDay())
daysCnt, day.indexOnMonthView, event.getIsAllDay(), event.isPastEvent)
allEvents.add(monthViewEvent)
}
}
@ -236,16 +238,16 @@ class MonthView(context: Context, attrs: AttributeSet, defStyle: Int) : View(con
bgRectF.set(bgLeft, bgTop, bgRight, bgBottom)
canvas.drawRoundRect(bgRectF, BG_CORNER_RADIUS, BG_CORNER_RADIUS, getEventBackgroundColor(event, startDayIndex, endDayIndex))
drawEventTitle(event.title, canvas, xPos, yPos + verticalOffset, bgRight - bgLeft - smallPadding, event.color, startDayIndex, endDayIndex)
drawEventTitle(event, canvas, xPos, yPos + verticalOffset, bgRight - bgLeft - smallPadding, startDayIndex, endDayIndex)
for (i in 0 until Math.min(event.daysCnt, 7 - event.startDayIndex % 7)) {
dayVerticalOffsets.put(event.startDayIndex + i, verticalOffset + eventTitleHeight + smallPadding * 2)
}
}
private fun drawEventTitle(title: String, canvas: Canvas, x: Float, y: Float, availableWidth: Float, eventColor: Int, startDay: DayMonthly, endDay: DayMonthly) {
val ellipsized = TextUtils.ellipsize(title, eventTitlePaint, availableWidth - smallPadding, TextUtils.TruncateAt.END)
canvas.drawText(title, 0, ellipsized.length, x + smallPadding * 2, y, getEventTitlePaint(eventColor, startDay, endDay))
private fun drawEventTitle(event: MonthViewEvent, canvas: Canvas, x: Float, y: Float, availableWidth: Float, startDay: DayMonthly, endDay: DayMonthly) {
val ellipsized = TextUtils.ellipsize(event.title, eventTitlePaint, availableWidth - smallPadding, TextUtils.TruncateAt.END)
canvas.drawText(event.title, 0, ellipsized.length, x + smallPadding * 2, y, getEventTitlePaint(event, startDay, endDay))
}
private fun getTextPaint(startDay: DayMonthly): Paint {
@ -269,16 +271,16 @@ class MonthView(context: Context, attrs: AttributeSet, defStyle: Int) : View(con
private fun getEventBackgroundColor(event: MonthViewEvent, startDay: DayMonthly, endDay: DayMonthly): Paint {
var paintColor = event.color
if (!startDay.isThisMonth && !endDay.isThisMonth) {
if ((!startDay.isThisMonth && !endDay.isThisMonth) || (dimPastEvents && event.isPastEvent)) {
paintColor = paintColor.adjustAlpha(LOW_ALPHA)
}
return getColoredPaint(paintColor)
}
private fun getEventTitlePaint(color: Int, startDay: DayMonthly, endDay: DayMonthly): Paint {
var paintColor = color.getContrastColor()
if (!startDay.isThisMonth && !endDay.isThisMonth) {
private fun getEventTitlePaint(event: MonthViewEvent, startDay: DayMonthly, endDay: DayMonthly): Paint {
var paintColor = event.color.getContrastColor()
if ((!startDay.isThisMonth && !endDay.isThisMonth) || (dimPastEvents && event.isPastEvent)) {
paintColor = paintColor.adjustAlpha(LOW_ALPHA)
}

View File

@ -1,10 +0,0 @@
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportHeight="108"
android:viewportWidth="108">
<path
android:fillColor="#FFFFFF"
android:pathData="m58.08,70.24 l-7.64,0 0,-7.64 7.64,0 0,7.64zM69.49,51.37 L61.85,51.37 61.85,59.01 69.49,59.01 69.49,51.37zM46.66,51.19 L39.02,51.19 39.02,58.83 46.66,58.83 46.66,51.19zM58.08,51.19 L50.44,51.19 50.44,58.83 58.08,58.83 58.08,51.19zM46.66,70.24 L46.66,62.6 39.02,62.6 39.02,70.24 46.66,70.24zM69.49,62.6 L61.85,62.6 61.85,70.24 69.49,70.24 69.49,62.6zM72.99,37.1 L72.99,47.97 72.99,74.38 35.71,74.38 35.71,47.97 35.71,37.1 41.79,37.1 41.79,32.32 44.09,32.32 44.09,37.1 53.11,37.1 53.11,32.32 55.41,32.32 55.41,37.1 64.52,37.1 64.52,32.32 66.91,32.32 66.91,37.1 72.99,37.1zM71.79,47.97 L36.82,47.97 36.82,73.19 71.79,73.19 71.79,47.97z"/>
</vector>

View File

@ -374,8 +374,6 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/event_repetition_divider"
android:layout_marginBottom="@dimen/medium_margin"
android:layout_marginTop="@dimen/medium_margin"
android:layout_toEndOf="@+id/event_caldav_calendar_image"
android:layout_toRightOf="@+id/event_caldav_calendar_image"
android:background="?attr/selectableItemBackground"

View File

@ -147,28 +147,6 @@
</RelativeLayout>
<RelativeLayout
android:id="@+id/settings_delete_all_events_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/medium_margin"
android:background="?attr/selectableItemBackground"
android:paddingBottom="@dimen/bigger_margin"
android:paddingLeft="@dimen/normal_margin"
android:paddingRight="@dimen/normal_margin"
android:paddingTop="@dimen/bigger_margin">
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/settings_delete_all_events"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:paddingLeft="@dimen/medium_margin"
android:paddingRight="@dimen/medium_margin"
android:text="@string/delete_all_events"/>
</RelativeLayout>
<View
android:id="@+id/reminders_divider"
android:layout_width="match_parent"
@ -210,6 +188,29 @@
</RelativeLayout>
<RelativeLayout
android:id="@+id/settings_loop_reminders_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/medium_margin"
android:background="?attr/selectableItemBackground"
android:paddingBottom="@dimen/activity_margin"
android:paddingLeft="@dimen/normal_margin"
android:paddingRight="@dimen/normal_margin"
android:paddingTop="@dimen/activity_margin">
<com.simplemobiletools.commons.views.MySwitchCompat
android:id="@+id/settings_loop_reminders"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@null"
android:clickable="false"
android:paddingLeft="@dimen/medium_margin"
android:paddingStart="@dimen/medium_margin"
android:text="@string/loop_reminders"/>
</RelativeLayout>
<RelativeLayout
android:id="@+id/settings_reminder_sound_holder"
android:layout_width="match_parent"
@ -498,7 +499,6 @@
android:id="@+id/settings_show_grid_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/medium_margin"
android:background="?attr/selectableItemBackground"
android:paddingBottom="@dimen/activity_margin"
android:paddingLeft="@dimen/normal_margin"
@ -615,10 +615,10 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:paddingBottom="@dimen/bigger_margin"
android:paddingBottom="@dimen/activity_margin"
android:paddingLeft="@dimen/normal_margin"
android:paddingRight="@dimen/normal_margin"
android:paddingTop="@dimen/bigger_margin">
android:paddingTop="@dimen/activity_margin">
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/settings_font_size_label"
@ -643,5 +643,88 @@
android:clickable="false"/>
</RelativeLayout>
<RelativeLayout
android:id="@+id/settings_customize_widget_colors_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:paddingBottom="@dimen/activity_margin"
android:paddingLeft="@dimen/normal_margin"
android:paddingRight="@dimen/normal_margin"
android:paddingTop="@dimen/activity_margin">
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/settings_customize_widget_colors_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:paddingLeft="@dimen/medium_margin"
android:paddingStart="@dimen/medium_margin"
android:text="@string/customize_widget_colors"/>
</RelativeLayout>
<View
android:id="@+id/events_divider"
android:layout_width="match_parent"
android:layout_height="1px"
android:background="@color/divider_grey"
android:importantForAccessibility="no"/>
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/events_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/bigger_margin"
android:layout_marginStart="@dimen/bigger_margin"
android:layout_marginTop="@dimen/activity_margin"
android:text="@string/events"
android:textAllCaps="true"
android:textSize="@dimen/smaller_text_size"/>
<RelativeLayout
android:id="@+id/settings_dim_past_events_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/medium_margin"
android:background="?attr/selectableItemBackground"
android:paddingBottom="@dimen/activity_margin"
android:paddingLeft="@dimen/normal_margin"
android:paddingRight="@dimen/normal_margin"
android:paddingTop="@dimen/activity_margin">
<com.simplemobiletools.commons.views.MySwitchCompat
android:id="@+id/settings_dim_past_events"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@null"
android:clickable="false"
android:paddingLeft="@dimen/medium_margin"
android:paddingStart="@dimen/medium_margin"
android:text="@string/dim_past_events"/>
</RelativeLayout>
<RelativeLayout
android:id="@+id/settings_delete_all_events_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:paddingBottom="@dimen/bigger_margin"
android:paddingLeft="@dimen/normal_margin"
android:paddingRight="@dimen/normal_margin"
android:paddingTop="@dimen/bigger_margin">
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/settings_delete_all_events"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:paddingLeft="@dimen/medium_margin"
android:paddingRight="@dimen/medium_margin"
android:text="@string/delete_all_events"/>
</RelativeLayout>
</LinearLayout>
</ScrollView>

View File

@ -5,7 +5,6 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingLeft="@dimen/activity_margin"
android:paddingRight="@dimen/activity_margin"
android:paddingTop="@dimen/activity_margin">
@ -13,6 +12,7 @@
android:id="@+id/import_events_event_type_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/activity_margin"
android:text="@string/default_event_type"
android:textSize="@dimen/smaller_text_size"/>
@ -20,6 +20,7 @@
android:id="@+id/import_event_type_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/activity_margin"
android:background="?attr/selectableItemBackground"
android:padding="@dimen/small_margin">
@ -42,4 +43,14 @@
android:clickable="false"/>
</RelativeLayout>
<com.simplemobiletools.commons.views.MyAppCompatCheckbox
android:id="@+id/import_events_checkbox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/normal_margin"
android:paddingBottom="@dimen/activity_margin"
android:paddingTop="@dimen/activity_margin"
android:text="@string/override_event_types"/>
</LinearLayout>

View File

@ -18,14 +18,14 @@
android:paddingBottom="@dimen/medium_margin"
android:paddingTop="@dimen/medium_margin">
<com.simplemobiletools.commons.views.MyTextView
<TextView
android:id="@+id/event_item_start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="@dimen/day_text_size"
tools:text="13:00"/>
<com.simplemobiletools.commons.views.MyTextView
<TextView
android:id="@+id/event_item_end"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@ -33,7 +33,7 @@
android:text="15:00"
android:textSize="@dimen/day_text_size"/>
<com.simplemobiletools.commons.views.MyTextView
<TextView
android:id="@+id/event_section_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@ -46,7 +46,7 @@
android:textSize="@dimen/day_text_size"
tools:text="Event title"/>
<com.simplemobiletools.commons.views.MyTextView
<TextView
android:id="@+id/event_item_description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@ -54,7 +54,6 @@
android:layout_marginLeft="@dimen/activity_margin"
android:layout_toLeftOf="@+id/event_item_color"
android:layout_toRightOf="@+id/event_item_end"
android:alpha=".4"
android:ellipsize="end"
android:maxLines="1"
android:paddingRight="@dimen/activity_margin"

View File

@ -20,14 +20,14 @@
android:paddingRight="@dimen/activity_margin"
android:paddingTop="@dimen/small_margin">
<com.simplemobiletools.commons.views.MyTextView
<TextView
android:id="@+id/event_item_start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="@dimen/day_text_size"
tools:text="13:00"/>
<com.simplemobiletools.commons.views.MyTextView
<TextView
android:id="@+id/event_item_end"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@ -35,7 +35,7 @@
android:text="15:00"
android:textSize="@dimen/day_text_size"/>
<com.simplemobiletools.commons.views.MyTextView
<TextView
android:id="@+id/event_section_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@ -48,7 +48,7 @@
android:textSize="@dimen/day_text_size"
tools:text="Event title"/>
<com.simplemobiletools.commons.views.MyTextView
<TextView
android:id="@+id/event_item_description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@ -56,7 +56,6 @@
android:layout_marginLeft="@dimen/activity_margin"
android:layout_toLeftOf="@+id/event_item_color"
android:layout_toRightOf="@+id/event_item_end"
android:alpha=".4"
android:ellipsize="end"
android:maxLines="1"
android:paddingRight="@dimen/activity_margin"

View File

@ -44,7 +44,6 @@
android:layout_marginLeft="@dimen/big_margin"
android:layout_toLeftOf="@+id/event_item_color"
android:layout_toRightOf="@+id/event_item_end"
android:alpha=".4"
android:ellipsize="end"
android:maxLines="1"
android:paddingRight="@dimen/activity_margin"

View File

@ -11,6 +11,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:overScrollMode="never"
android:paddingTop="@dimen/medium_margin"
android:scrollbars="vertical"
android:visibility="gone"
@ -20,10 +21,26 @@
android:id="@+id/calendar_empty_list_placeholder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:lineSpacingExtra="1dp"
android:padding="@dimen/big_margin"
android:layout_centerHorizontal="true"
android:layout_marginTop="@dimen/activity_margin"
android:gravity="center"
android:paddingLeft="@dimen/activity_margin"
android:paddingRight="@dimen/activity_margin"
android:text="@string/no_upcoming_events"
android:textSize="@dimen/bigger_text_size"
android:visibility="gone"/>
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/calendar_empty_list_placeholder_2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/calendar_empty_list_placeholder"
android:layout_centerHorizontal="true"
android:gravity="center"
android:paddingBottom="@dimen/medium_margin"
android:paddingTop="@dimen/medium_margin"
android:text="@string/create_new_event"
android:textSize="@dimen/bigger_text_size"
android:visibility="gone"/>
</RelativeLayout>

View File

@ -20,7 +20,7 @@
android:paddingTop="@dimen/medium_margin"
app:layoutManager="com.simplemobiletools.commons.views.MyLinearLayoutManager"/>
<Button
<ImageView
android:id="@+id/config_bg_color"
android:layout_width="@dimen/widget_colorpicker_size"
android:layout_height="@dimen/widget_colorpicker_size"
@ -44,7 +44,7 @@
android:paddingRight="@dimen/activity_margin"/>
</RelativeLayout>
<Button
<ImageView
android:id="@+id/config_text_color"
android:layout_width="@dimen/widget_colorpicker_size"
android:layout_height="@dimen/widget_colorpicker_size"

View File

@ -15,7 +15,7 @@
android:layout_above="@+id/config_bg_color"
android:layout_marginBottom="@dimen/activity_margin"/>
<Button
<ImageView
android:id="@+id/config_bg_color"
android:layout_width="@dimen/widget_colorpicker_size"
android:layout_height="@dimen/widget_colorpicker_size"
@ -39,7 +39,7 @@
android:paddingRight="@dimen/activity_margin"/>
</RelativeLayout>
<Button
<ImageView
android:id="@+id/config_text_color"
android:layout_width="@dimen/widget_colorpicker_size"
android:layout_height="@dimen/widget_colorpicker_size"

View File

@ -11,6 +11,11 @@
android:icon="@drawable/ic_delete"
android:title="@string/delete"
app:showAsAction="ifRoom"/>
<item
android:id="@+id/duplicate"
android:icon="@drawable/ic_copy"
android:title="@string/duplicate_event"
app:showAsAction="ifRoom"/>
<item
android:id="@+id/share"
android:icon="@drawable/ic_share"

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/color_primary"/>
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
<background android:drawable="@color/md_orange_700"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/md_amber_700"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/md_blue_700"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/md_blue_grey_700"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/md_brown_700"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/md_cyan_700"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/md_deep_orange_700"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/md_deep_purple_700"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/md_green_700"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/md_grey_black"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/md_indigo_700"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/md_light_blue_700"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/md_light_green_700"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/md_lime_700"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/md_pink_700"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/md_purple_700"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/md_red_700"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/md_teal_700"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/md_yellow_700"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Some files were not shown because too many files have changed in this diff Show More