Updated dependencies and cleanup

This commit is contained in:
Erik C. Thauvin 2019-09-26 15:27:41 -07:00
parent 23d2953c6b
commit df097598cd
30 changed files with 601 additions and 321 deletions

View file

@ -1,29 +1,116 @@
<component name="ProjectCodeStyleConfiguration"> <component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173"> <code_scheme name="Project" version="173">
<Objective-C-extensions> <codeStyleSettings language="XML">
<file> <indentOptions>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import" /> <option name="CONTINUATION_INDENT_SIZE" value="4" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Macro" /> </indentOptions>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Typedef" /> <arrangement>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Enum" /> <rules>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Constant" /> <section>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Global" /> <rule>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Struct" /> <match>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="FunctionPredecl" /> <AND>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Function" /> <NAME>xmlns:android</NAME>
</file> <XML_ATTRIBUTE />
<class> <XML_NAMESPACE>^$</XML_NAMESPACE>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Property" /> </AND>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Synthesize" /> </match>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InitMethod" /> </rule>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="StaticMethod" /> </section>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InstanceMethod" /> <section>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="DeallocMethod" /> <rule>
</class> <match>
<extensions> <AND>
<pair source="cpp" header="h" fileNamingConvention="NONE" /> <NAME>xmlns:.*</NAME>
<pair source="c" header="h" fileNamingConvention="NONE" /> <XML_ATTRIBUTE />
</extensions> <XML_NAMESPACE>^$</XML_NAMESPACE>
</Objective-C-extensions> </AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:id</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:name</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>name</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>style</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
<order>ANDROID_ATTRIBUTE_ORDER</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>.*</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
</rules>
</arrangement>
</codeStyleSettings>
</code_scheme> </code_scheme>
</component> </component>

4
.idea/encodings.xml generated Normal file
View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding" addBOMForNewFiles="with NO BOM" />
</project>

21
.idea/misc.xml generated
View file

@ -5,26 +5,41 @@
<option name="myDefaultNotNull" value="android.support.annotation.NonNull" /> <option name="myDefaultNotNull" value="android.support.annotation.NonNull" />
<option name="myNullables"> <option name="myNullables">
<value> <value>
<list size="4"> <list size="12">
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" /> <item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" /> <item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" />
<item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" /> <item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" />
<item index="3" class="java.lang.String" itemvalue="android.support.annotation.Nullable" /> <item index="3" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
<item index="4" class="java.lang.String" itemvalue="javax.annotation.CheckForNull" />
<item index="5" class="java.lang.String" itemvalue="androidx.annotation.Nullable" />
<item index="6" class="java.lang.String" itemvalue="androidx.annotation.RecentlyNullable" />
<item index="7" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.qual.Nullable" />
<item index="8" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NullableDecl" />
<item index="9" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NullableType" />
<item index="10" class="java.lang.String" itemvalue="android.annotation.Nullable" />
<item index="11" class="java.lang.String" itemvalue="com.android.annotations.Nullable" />
</list> </list>
</value> </value>
</option> </option>
<option name="myNotNulls"> <option name="myNotNulls">
<value> <value>
<list size="4"> <list size="11">
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" /> <item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" />
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nonnull" /> <item index="1" class="java.lang.String" itemvalue="javax.annotation.Nonnull" />
<item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.NonNull" /> <item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.NonNull" />
<item index="3" class="java.lang.String" itemvalue="android.support.annotation.NonNull" /> <item index="3" class="java.lang.String" itemvalue="android.support.annotation.NonNull" />
<item index="4" class="java.lang.String" itemvalue="androidx.annotation.NonNull" />
<item index="5" class="java.lang.String" itemvalue="androidx.annotation.RecentlyNonNull" />
<item index="6" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.qual.NonNull" />
<item index="7" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NonNullDecl" />
<item index="8" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NonNullType" />
<item index="9" class="java.lang.String" itemvalue="android.annotation.NonNull" />
<item index="10" class="java.lang.String" itemvalue="com.android.annotations.NonNull" />
</list> </list>
</value> </value>
</option> </option>
</component> </component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" project-jdk-name="1.8" project-jdk-type="JavaSDK"> <component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" project-jdk-name="JDK" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" /> <output url="file://$PROJECT_DIR$/build/classes" />
</component> </component>
<component name="ProjectType"> <component name="ProjectType">

View file

@ -1,21 +1,20 @@
plugins { plugins {
id "org.jlleitschuh.gradle.ktlint" version "6.2.1" id 'com.android.application'
id 'kotlin-android'
id 'kotlin-android-extensions'
id 'kotlin-kapt'
id 'org.jmailen.kotlinter' version '2.1.1'
id 'com.github.ben-manes.versions' version '0.25.0'
} }
//noinspection GradleCompatible
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
android { android {
compileSdkVersion 27 compileSdkVersion 28
buildToolsVersion '28.0.3' buildToolsVersion '28.0.3'
defaultConfig { defaultConfig {
applicationId "net.thauvin.erik.android.tesremoteprogrammer" applicationId "net.thauvin.erik.android.tesremoteprogrammer"
minSdkVersion 21 minSdkVersion 26
targetSdkVersion 27 targetSdkVersion 28
versionCode 1 versionCode 1
versionName "1.0" versionName "1.0"
buildConfigField "long", "TIMESTAMP", System.currentTimeMillis() + "L" buildConfigField "long", "TIMESTAMP", System.currentTimeMillis() + "L"
@ -32,8 +31,8 @@ android {
} }
ext { ext {
anko_version = '0.10.7' anko_version = '0.10.8'
support_version = "27.1.1" support_version = "28.0.0"
} }
dependencies { dependencies {
@ -54,9 +53,6 @@ dependencies {
// https://github.com/JakeWharton/ViewPagerIndicator // https://github.com/JakeWharton/ViewPagerIndicator
implementation 'fr.avianey.com.viewpagerindicator:library:2.4.1.1@aar' implementation 'fr.avianey.com.viewpagerindicator:library:2.4.1.1@aar'
// https://github.com/AndroidDeveloperLB/AutoFitTextView
implementation 'com.github.AndroidDeveloperLB:AutoFitTextView:4'
// https://github.com/hotchemi/PermissionsDispatcher // https://github.com/hotchemi/PermissionsDispatcher
// Version 4.x does not work. // Version 4.x does not work.
implementation 'com.github.hotchemi:permissionsdispatcher:3.3.1' implementation 'com.github.hotchemi:permissionsdispatcher:3.3.1'
@ -82,3 +78,10 @@ repositories {
kapt { kapt {
//generateStubs = true //generateStubs = true
} }
kotlinter {
ignoreFailures = false
reporters = ['html']
experimentalRules = false
disabledRules = ['import-ordering']
}

View file

@ -1,7 +1,7 @@
/* /*
* App.kt * App.kt
* *
* Copyright 2016-2018 Erik C. Thauvin (erik@thauvin.net) * Copyright 2016-2019 Erik C. Thauvin (erik@thauvin.net)
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -25,10 +25,13 @@ import org.acra.ACRA
import org.acra.ReportingInteractionMode import org.acra.ReportingInteractionMode
import org.acra.annotation.ReportsCrashes import org.acra.annotation.ReportsCrashes
@ReportsCrashes(mailTo = "erik@thauvin.net", @Suppress("unused")
@ReportsCrashes(
mailTo = "erik@thauvin.net",
mode = ReportingInteractionMode.DIALOG, mode = ReportingInteractionMode.DIALOG,
reportSenderFactoryClasses = [CrashEmailFactory::class], reportSenderFactoryClasses = [CrashEmailFactory::class],
reportDialogClass = CrashReportActivity::class) reportDialogClass = CrashReportActivity::class
)
open class App : Application() { open class App : Application() {
override fun attachBaseContext(base: Context) { override fun attachBaseContext(base: Context) {
super.attachBaseContext(base) super.attachBaseContext(base)

View file

@ -1,7 +1,7 @@
/* /*
* MainActivity.kt * MainActivity.kt
* *
* Copyright 2016-2018 Erik C. Thauvin (erik@thauvin.net) * Copyright 2016-2019 Erik C. Thauvin (erik@thauvin.net)
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -24,13 +24,11 @@ import android.app.AlertDialog
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.graphics.Typeface import android.graphics.Typeface
import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.support.v7.app.AppCompatActivity import android.support.v7.app.AppCompatActivity
import android.text.Html import android.text.Html
import android.text.InputFilter import android.text.InputFilter
import android.text.InputType import android.text.InputType
import android.text.Spanned
import android.text.TextUtils import android.text.TextUtils
import android.util.TypedValue import android.util.TypedValue
import android.view.Menu import android.view.Menu
@ -89,7 +87,8 @@ class MainActivity : AppCompatActivity(), AnkoLogger {
R.raw.dks_1819, R.raw.dks_1819,
R.raw.linear_ae_100, R.raw.linear_ae_100,
R.raw.linear_ae_500, R.raw.linear_ae_500,
R.raw.dks_1803_1808_1810) R.raw.dks_1803_1808_1810
)
private val readRequestCode = 42 private val readRequestCode = 42
companion object { companion object {
@ -97,14 +96,7 @@ class MainActivity : AppCompatActivity(), AnkoLogger {
const val QUOTE = "'" const val QUOTE = "'"
} }
private fun fromHtml(s: String): Spanned { private fun fromHtml(s: String) = Html.fromHtml(s, Html.FROM_HTML_MODE_LEGACY)
if (Build.VERSION.SDK_INT >= 24) {
return Html.fromHtml(s, Html.FROM_HTML_MODE_LEGACY)
} else {
@Suppress("DEPRECATION")
return Html.fromHtml(s)
}
}
private fun initConfigurations() { private fun initConfigurations() {
try { try {
@ -115,8 +107,10 @@ class MainActivity : AppCompatActivity(), AnkoLogger {
val confs = Configurations() val confs = Configurations()
defaultConfigurations.forEach { defaultConfigurations.forEach {
config = Gson().fromJson(InputStreamReader(resources.openRawResource(it)), config = Gson().fromJson(
Config::class.java) InputStreamReader(resources.openRawResource(it)),
Config::class.java
)
if (BuildConfig.DEBUG) { if (BuildConfig.DEBUG) {
val errors = StringBuilder() val errors = StringBuilder()
@ -145,7 +139,8 @@ class MainActivity : AppCompatActivity(), AnkoLogger {
extraTitle = "Last Update" extraTitle = "Last Update"
extra = DateFormat.getDateInstance(DateFormat.LONG, Locale.getDefault()).format( extra = DateFormat.getDateInstance(DateFormat.LONG, Locale.getDefault()).format(
Date(BuildConfig.TIMESTAMP)).toString() Date(BuildConfig.TIMESTAMP)
).toString()
emailAddress = "erik@thauvin.net" emailAddress = "erik@thauvin.net"
emailSubject = "${getString(R.string.app_name)} ${BuildConfig.VERSION_NAME} Support" emailSubject = "${getString(R.string.app_name)} ${BuildConfig.VERSION_NAME} Support"
@ -172,8 +167,10 @@ class MainActivity : AppCompatActivity(), AnkoLogger {
val errors = StringBuilder() val errors = StringBuilder()
val tmp: Config? = try { val tmp: Config? = try {
Gson().fromJson(InputStreamReader(contentResolver.openInputStream(intent.data)), Gson().fromJson(
Config::class.java) InputStreamReader(contentResolver.openInputStream(intent.data!!)),
Config::class.java
)
} catch (jse: JsonSyntaxException) { } catch (jse: JsonSyntaxException) {
val cause = jse.cause val cause = jse.cause
if (cause != null) { if (cause != null) {
@ -221,7 +218,7 @@ class MainActivity : AppCompatActivity(), AnkoLogger {
// config name // config name
textView { textView {
text = name.toUpperCase() text = name.toUpperCase(Locale.getDefault())
bottomPadding = dip(5) bottomPadding = dip(5)
typeface = Typeface.DEFAULT_BOLD typeface = Typeface.DEFAULT_BOLD
setTextSize(TypedValue.COMPLEX_UNIT_DIP, 24f) setTextSize(TypedValue.COMPLEX_UNIT_DIP, 24f)
@ -241,7 +238,12 @@ class MainActivity : AppCompatActivity(), AnkoLogger {
setText(phone) setText(phone)
} }
setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_call_black_24dp, 0) setCompoundDrawablesWithIntrinsicBounds(
0,
0,
R.drawable.ic_call_black_24dp,
0
)
setOnFocusChangeListener { view, hasFocus -> setOnFocusChangeListener { view, hasFocus ->
if (!hasFocus) { if (!hasFocus) {
phone = (view as EditText).text.toString() phone = (view as EditText).text.toString()
@ -259,7 +261,12 @@ class MainActivity : AppCompatActivity(), AnkoLogger {
inputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_PASSWORD inputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_PASSWORD
hint = getString(R.string.hint_master_code) hint = getString(R.string.hint_master_code)
filters = arrayOf(InputFilter.LengthFilter(size)) filters = arrayOf(InputFilter.LengthFilter(size))
setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_lock_question_black_24dp, 0) setCompoundDrawablesWithIntrinsicBounds(
0,
0,
R.drawable.ic_lock_question_black_24dp,
0
)
imeOptions = EditorInfo.IME_ACTION_DONE imeOptions = EditorInfo.IME_ACTION_DONE
if (master.isNotBlank()) { if (master.isNotBlank()) {
@ -303,7 +310,11 @@ class MainActivity : AppCompatActivity(), AnkoLogger {
titles.add(it.title) titles.add(it.title)
} }
adapter = ArrayAdapter<String>(this@MainActivity, android.R.layout.simple_list_item_1, titles) adapter = ArrayAdapter(
this@MainActivity,
android.R.layout.simple_list_item_1,
titles
)
isTextFilterEnabled = true isTextFilterEnabled = true
isScrollbarFadingEnabled = false isScrollbarFadingEnabled = false
onItemClickListener = AdapterView.OnItemClickListener { _, _, position, _ -> onItemClickListener = AdapterView.OnItemClickListener { _, _, position, _ ->
@ -311,7 +322,8 @@ class MainActivity : AppCompatActivity(), AnkoLogger {
saveConfig() saveConfig()
startActivity<ProgrammingActivity>( startActivity<ProgrammingActivity>(
"net.thauvin.erik.android.tesremoteprogrammer.models.Params" to config.params, "net.thauvin.erik.android.tesremoteprogrammer.models.Params" to config.params,
"net.thauvin.erik.android.tesremoteprogrammer.models.Option" to opts[position]) "net.thauvin.erik.android.tesremoteprogrammer.models.Option" to opts[position]
)
} }
} }
} }
@ -444,129 +456,194 @@ class MainActivity : AppCompatActivity(), AnkoLogger {
with(option) { with(option) {
// title // title
if (title.isBlank()) { if (title.isBlank()) {
errors.append(getString( errors.append(
getString(
R.string.validate_missing_opts_prop, R.string.validate_missing_opts_prop,
i + 1, i + 1,
"title")) "title"
)
)
} }
// nosteps/nodial // nosteps/nodial
if (nosteps && nodial) { if (nosteps && nodial) {
errors.append(getString( errors.append(
getString(
R.string.validate_invalid_option, R.string.validate_invalid_option,
i + 1, i + 1,
"nodial/nosteps")) "nodial/nosteps"
)
)
} }
// dtmf // dtmf
if (dtmf.isBlank()) { if (dtmf.isBlank()) {
errors.append(getString( errors.append(
getString(
R.string.validate_missing_opts_prop, R.string.validate_missing_opts_prop,
i + 1, i + 1,
"dtmf")) "dtmf"
)
)
} else if (!nodial && fields.isEmpty()) { // fields missing } else if (!nodial && fields.isEmpty()) { // fields missing
errors.append(getString( errors.append(
getString(
R.string.validate_missing_opts_prop, R.string.validate_missing_opts_prop,
i + 1, i + 1,
"fields")) "fields"
)
)
} else { } else {
val blank = "\\0" val blank = "\\0"
val mock = Dtmf.mock(option, blank) val mock = Dtmf.mock(option, blank)
if (!mock.contains(MainActivity.PAUSE)) { // no pause if (!mock.contains(PAUSE)) { // no pause
errors.append(getString( errors.append(
getString(
R.string.validate_invalid_opts_prop, R.string.validate_invalid_opts_prop,
i + 1, i + 1,
"dtmf", "dtmf",
getString(R.string.validate_dtmf_nopause))) getString(R.string.validate_dtmf_nopause)
)
)
} }
if (!Dtmf.validate(mock, if (!Dtmf.validate(
"${MainActivity.PAUSE}${params.ack}${params.alt}$blank", nodial)) { mock,
errors.append(getString( "$PAUSE${params.ack}${params.alt}$blank", nodial
)) {
errors.append(
getString(
R.string.validate_invalid_opts_prop, R.string.validate_invalid_opts_prop,
i + 1, i + 1,
"dtmf", "dtmf",
mock.replace(blank, "&#10003;"))) mock.replace(blank, "&#10003;")
)
)
} }
} }
// fields // fields
fields.forEachIndexed { j, field -> fields.forEachIndexed { j, field ->
if (field == null) { if (field == null) {
errors.append(getString( errors.append(
getString(
R.string.validate_syntax_error, R.string.validate_syntax_error,
"opts[${i + 1}], field[$j]")) "opts[${i + 1}], field[$j]"
)
)
} else { } else {
with(field) { with(field) {
// size // size
if (size <= 0) { if (size <= 0) {
errors.append(getString( errors.append(
getString(
R.string.validate_invalid_field_prop, R.string.validate_invalid_field_prop,
i + 1, i + 1,
j + 1, j + 1,
resources.getQuantityString(R.plurals.error_prop, 1), resources.getQuantityString(
"size=$size")) R.plurals.error_prop,
1
),
"size=$size"
)
)
} }
// digits // digits
if (digits.isNotBlank() && !digits.isDigits()) { if (digits.isNotBlank() && !digits.isDigits()) {
errors.append(getString( errors.append(
getString(
R.string.validate_invalid_field_prop, R.string.validate_invalid_field_prop,
i + 1, i + 1,
j + 1, j + 1,
resources.getQuantityString(R.plurals.error_prop, 1), resources.getQuantityString(
"digits='$digits'")) R.plurals.error_prop,
1
),
"digits='$digits'"
)
)
} }
// minSize // minSize
if (minSize >= 0 && minSize > size) { if (minSize >= 0 && minSize > size) {
errors.append(getString( errors.append(
getString(
R.string.validate_invalid_field_prop, R.string.validate_invalid_field_prop,
i + 1, i + 1,
j + 1, j + 1,
resources.getQuantityString(R.plurals.error_prop, 2), resources.getQuantityString(
"minSize=$minSize > size=$size")) R.plurals.error_prop,
2
),
"minSize=$minSize > size=$size"
)
)
} }
// numeric fields only // numeric fields only
if (!alpha) { if (!alpha) {
if (minSize == 0) { if (minSize == 0) {
errors.append(getString( errors.append(
getString(
R.string.validate_invalid_field_prop, R.string.validate_invalid_field_prop,
i + 1, i + 1,
j + 1, j + 1,
resources.getQuantityString(R.plurals.error_prop, 1), resources.getQuantityString(
"minSize=$minSize")) R.plurals.error_prop,
1
),
"minSize=$minSize"
)
)
} }
// min/max // min/max
if (min >= 0 || max >= 0) { if (min >= 0 || max >= 0) {
if (max < 1) { if (max < 1) {
errors.append(getString( errors.append(
getString(
R.string.validate_invalid_field_prop, R.string.validate_invalid_field_prop,
i + 1, i + 1,
j + 1, j + 1,
resources.getQuantityString(R.plurals.error_prop, 1), resources.getQuantityString(
"max=$max")) R.plurals.error_prop,
1
),
"max=$max"
)
)
} }
if (min < 0) { if (min < 0) {
errors.append(getString( errors.append(
getString(
R.string.validate_invalid_field_prop, R.string.validate_invalid_field_prop,
i + 1, i + 1,
j + 1, j + 1,
resources.getQuantityString(R.plurals.error_prop, 1), resources.getQuantityString(
"min=$min")) R.plurals.error_prop,
1
),
"min=$min"
)
)
} }
if (min > max) { if (min > max) {
errors.append(getString( errors.append(
getString(
R.string.validate_invalid_field_prop, R.string.validate_invalid_field_prop,
i + 1, i + 1,
j + 1, j + 1,
resources.getQuantityString(R.plurals.error_prop, 2), resources.getQuantityString(
"min=$min > max=$max")) R.plurals.error_prop,
2
),
"min=$min > max=$max"
)
)
} }
} }
@ -575,24 +652,36 @@ class MainActivity : AppCompatActivity(), AnkoLogger {
// minSize/min // minSize/min
if (min >= 0 && minSize > 0) { if (min >= 0 && minSize > 0) {
if (min.toString().length != minSize) { if (min.toString().length != minSize) {
errors.append(getString( errors.append(
getString(
R.string.validate_invalid_field_prop, R.string.validate_invalid_field_prop,
i + 1, i + 1,
j + 1, j + 1,
resources.getQuantityString(R.plurals.error_prop, 2), resources.getQuantityString(
"minSize=$minSize/min=$min")) R.plurals.error_prop,
2
),
"minSize=$minSize/min=$min"
)
)
} }
} }
// size/max // size/max
if (size > 0 && max > 0) { if (size > 0 && max > 0) {
if (max.toString().length != size) { if (max.toString().length != size) {
errors.append(getString( errors.append(
getString(
R.string.validate_invalid_field_prop, R.string.validate_invalid_field_prop,
i + 1, i + 1,
j + 1, j + 1,
resources.getQuantityString(R.plurals.error_prop, 2), resources.getQuantityString(
"size=$size/max=$max")) R.plurals.error_prop,
2
),
"size=$size/max=$max"
)
)
} }
} }
} }
@ -600,10 +689,13 @@ class MainActivity : AppCompatActivity(), AnkoLogger {
// unused fields // unused fields
if (!dtmf.contains(Dtmf.DTMF_FIELD.format(j + 1))) { if (!dtmf.contains(Dtmf.DTMF_FIELD.format(j + 1))) {
errors.append(getString( errors.append(
getString(
R.string.validate_unused_field, R.string.validate_unused_field,
i + 1, i + 1,
j + 1)) j + 1
)
)
} }
} }
} }
@ -626,8 +718,10 @@ class MainActivity : AppCompatActivity(), AnkoLogger {
first.error = getString(R.string.error_required) first.error = getString(R.string.error_required)
isValid = false isValid = false
} else if (second > 0 && first.text.length != second) { } else if (second > 0 && first.text.length != second) {
first.error = getString(R.string.error_invalid_size, second, first.error = getString(
resources.getQuantityString(R.plurals.error_digit, second), "") R.string.error_invalid_size, second,
resources.getQuantityString(R.plurals.error_digit, second), ""
)
isValid = false isValid = false
} }
} }

View file

@ -1,7 +1,7 @@
/* /*
* ProgrammingActivity.kt * ProgrammingActivity.kt
* *
* Copyright 2016-2018 Erik C. Thauvin (erik@thauvin.net) * Copyright 2016-2019 Erik C. Thauvin (erik@thauvin.net)
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -77,8 +77,8 @@ class ProgrammingActivity : AppCompatActivity(), AnkoLogger {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
val params: Params = intent.extras.getParcelable("net.thauvin.erik.android.tesremoteprogrammer.models.Params") val params: Params = intent.extras!!.getParcelable("net.thauvin.erik.android.tesremoteprogrammer.models.Params")
val option: Option = intent.extras.getParcelable("net.thauvin.erik.android.tesremoteprogrammer.models.Option") val option: Option = intent.extras!!.getParcelable("net.thauvin.erik.android.tesremoteprogrammer.models.Option")
val fields = arrayListOf<EditText>() val fields = arrayListOf<EditText>()
coordinatorLayout { coordinatorLayout {
@ -135,14 +135,21 @@ class ProgrammingActivity : AppCompatActivity(), AnkoLogger {
} }
} else { } else {
inputType = InputType.TYPE_CLASS_PHONE inputType = InputType.TYPE_CLASS_PHONE
inputFilters.add(NumberFilter(field.digits, if (field.alt) params.alt else empty)) inputFilters.add(
NumberFilter(
field.digits,
if (field.alt) params.alt else empty
)
)
if (field.max != -1 && field.min != -1) { if (field.max != -1 && field.min != -1) {
inputFilters.add( inputFilters.add(
MinMaxFilter( MinMaxFilter(
field.min, field.min,
field.max, field.max,
field.size, field.size,
params.type.isDKS() || field.zeros)) params.type.isDKS() || field.zeros
)
)
} }
} }
@ -196,8 +203,18 @@ class ProgrammingActivity : AppCompatActivity(), AnkoLogger {
elevation = dip(6).toFloat() elevation = dip(6).toFloat()
}.setOnClickListener { }.setOnClickListener {
if (validateFields(params.type, fields, option)) { if (validateFields(params.type, fields, option)) {
val dtmf = Dtmf.build(params.type, params.master, params.ack, option, fields) val dtmf = Dtmf.build(
if (Dtmf.validate(dtmf, "${MainActivity.PAUSE}${params.ack}${params.alt}", option.nodial)) { params.type,
params.master,
params.ack,
option,
fields
)
if (Dtmf.validate(
dtmf,
"${MainActivity.PAUSE}${params.ack}${params.alt}",
option.nodial
)) {
val begin = if (params.begin.isNotBlank()) { val begin = if (params.begin.isNotBlank()) {
"${params.begin}${MainActivity.PAUSE}" "${params.begin}${MainActivity.PAUSE}"
} else { } else {
@ -245,21 +262,40 @@ class ProgrammingActivity : AppCompatActivity(), AnkoLogger {
}.setOnClickListener { }.setOnClickListener {
if (validateFieldsForCall(params.type, fields)) { if (validateFieldsForCall(params.type, fields)) {
if (validateFields(params.type, fields, option)) { if (validateFields(params.type, fields, option)) {
val dtmf = Dtmf.build(params.type, params.master, params.ack, option, fields) val dtmf = Dtmf.build(
if (Dtmf.validate(dtmf, "${MainActivity.PAUSE}${params.ack}${params.alt}", option.nodial)) { params.type,
params.master,
params.ack,
option,
fields
)
if (Dtmf.validate(
dtmf,
"${MainActivity.PAUSE}${params.ack}${params.alt}",
option.nodial
)) {
callWithPermissionCheck(params.phone, dtmf) callWithPermissionCheck(params.phone, dtmf)
} else { } else {
Snackbar.make(this@coordinatorLayout, Snackbar.make(
this@coordinatorLayout,
getString(R.string.error_invalid_dtmf, dtmf), getString(R.string.error_invalid_dtmf, dtmf),
Snackbar.LENGTH_LONG).show() Snackbar.LENGTH_LONG
).show()
} }
} else { } else {
Snackbar.make(this@coordinatorLayout, R.string.error_invalid_field, Snackbar.make(
Snackbar.LENGTH_LONG).show() this@coordinatorLayout, R.string.error_invalid_field,
Snackbar.LENGTH_LONG
).show()
} }
} else { } else {
val text = SpannableString(getString(R.string.error_invalid_field_for_call) + " ") val text = SpannableString(getString(R.string.error_invalid_field_for_call) + " ")
text.setSpan(ImageSpan(context, R.drawable.ic_menu_dialpad_lt), text.length - 1, text.length, 0) text.setSpan(
ImageSpan(context, R.drawable.ic_menu_dialpad_lt),
text.length - 1,
text.length,
0
)
Snackbar.make(this@coordinatorLayout, text, Snackbar.LENGTH_LONG).show() Snackbar.make(this@coordinatorLayout, text, Snackbar.LENGTH_LONG).show()
} }
} }
@ -310,19 +346,25 @@ class ProgrammingActivity : AppCompatActivity(), AnkoLogger {
if (v.text.isNullOrBlank()) { if (v.text.isNullOrBlank()) {
v.error = getString(R.string.error_required) v.error = getString(R.string.error_required)
isValid = false isValid = false
} else if (!validateSize(v.length(), if ((!type.isDKS() && !zeros) && min >= 0) min.toString().length else minSize, size)) { } else if (!validateSize(
v.length(),
if ((!type.isDKS() && !zeros) && min >= 0) min.toString().length else minSize,
size
)) {
if (minSize > 0) { if (minSize > 0) {
v.error = getString( v.error = getString(
R.string.error_invalid_size, R.string.error_invalid_size,
minSize, minSize,
resources.getQuantityString(R.plurals.error_digit, minSize), resources.getQuantityString(R.plurals.error_digit, minSize),
getString(R.string.error_minimum)) getString(R.string.error_minimum)
)
} else { } else {
v.error = getString( v.error = getString(
R.string.error_invalid_size, R.string.error_invalid_size,
size, size,
resources.getQuantityString(R.plurals.error_digit, size), resources.getQuantityString(R.plurals.error_digit, size),
empty) empty
)
} }
isValid = false isValid = false
} else if (min >= 0 && max > 0) { } else if (min >= 0 && max > 0) {

View file

@ -1,7 +1,7 @@
/* /*
* SplashActivity.kt * SplashActivity.kt
* *
* Copyright 2016-2018 Erik C. Thauvin (erik@thauvin.net) * Copyright 2016-2019 Erik C. Thauvin (erik@thauvin.net)
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -22,7 +22,6 @@ import android.support.v7.app.AppCompatActivity
import org.jetbrains.anko.startActivity import org.jetbrains.anko.startActivity
class SplashActivity : AppCompatActivity() { class SplashActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)

View file

@ -1,7 +1,7 @@
/* /*
* StepsActivity.kt * StepsActivity.kt
* *
* Copyright 2016-2018 Erik C. Thauvin (erik@thauvin.net) * Copyright 2016-2019 Erik C. Thauvin (erik@thauvin.net)
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View file

@ -1,7 +1,7 @@
/* /*
* StepsFragment.kt * StepsFragment.kt
* *
* Copyright 2016-2018 Erik C. Thauvin (erik@thauvin.net) * Copyright 2016-2019 Erik C. Thauvin (erik@thauvin.net)
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -63,7 +63,11 @@ class StepsFragment : Fragment() {
if (steps.isEmpty()) { if (steps.isEmpty()) {
activity.finish() activity.finish()
} else { } else {
frag_steps_title.text = getString(R.string.title_template_step, pageNumber + 1, steps.size) frag_steps_title.text = getString(
R.string.title_template_step,
pageNumber + 1,
steps.size
)
frag_steps.text = steps[pageNumber] frag_steps.text = steps[pageNumber]
} }
} }

View file

@ -1,7 +1,7 @@
/* /*
* AlphaFilter.kt * AlphaFilter.kt
* *
* Copyright 2016-2018 Erik C. Thauvin (erik@thauvin.net) * Copyright 2016-2019 Erik C. Thauvin (erik@thauvin.net)
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View file

@ -1,7 +1,7 @@
/* /*
* MinMaxFilter.kt * MinMaxFilter.kt
* *
* Copyright 2016-2018 Erik C. Thauvin (erik@thauvin.net) * Copyright 2016-2019 Erik C. Thauvin (erik@thauvin.net)
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -21,9 +21,21 @@ import android.text.InputFilter
import android.text.Spanned import android.text.Spanned
import org.jetbrains.anko.AnkoLogger import org.jetbrains.anko.AnkoLogger
class MinMaxFilter(private val min: Int, private val max: Int, private val size: Int, private val zeros: Boolean) : InputFilter, AnkoLogger { class MinMaxFilter(
private val min: Int,
private val max: Int,
private val size: Int,
private val zeros: Boolean
) : InputFilter, AnkoLogger {
override fun filter(source: CharSequence, start: Int, end: Int, dest: Spanned, dstart: Int, dend: Int): CharSequence? { override fun filter(
source: CharSequence,
start: Int,
end: Int,
dest: Spanned,
dstart: Int,
dend: Int
): CharSequence? {
val input = (dest.toString() + source.toString()) val input = (dest.toString() + source.toString())
if (isInRange(input, size, min, max, zeros)) { if (isInRange(input, size, min, max, zeros)) {

View file

@ -1,7 +1,7 @@
/* /*
* NumberFilter.kt * NumberFilter.kt
* *
* Copyright 2016-2018 Erik C. Thauvin (erik@thauvin.net) * Copyright 2016-2019 Erik C. Thauvin (erik@thauvin.net)
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -27,6 +27,14 @@ class NumberFilter(allowed: String, alt: String) : InputFilter, AnkoLogger {
private val allowed: String private val allowed: String
private val digits = "0123456789" private val digits = "0123456789"
init {
this.allowed = if (allowed.isDigits()) {
"$allowed$alt"
} else {
"$digits$alt"
}
}
override fun filter( override fun filter(
source: CharSequence, source: CharSequence,
start: Int, start: Int,
@ -52,12 +60,4 @@ class NumberFilter(allowed: String, alt: String) : InputFilter, AnkoLogger {
return sb.toString() return sb.toString()
} }
} }
init {
this.allowed = if (allowed.isDigits()) {
"$allowed$alt"
} else {
"$digits$alt"
}
}
} }

View file

@ -1,7 +1,7 @@
/* /*
* Config.kt * Config.kt
* *
* Copyright 2016-2018 Erik C. Thauvin (erik@thauvin.net) * Copyright 2016-2019 Erik C. Thauvin (erik@thauvin.net)
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -21,7 +21,10 @@ import android.os.Parcel
import android.os.Parcelable import android.os.Parcelable
import java.io.Serializable import java.io.Serializable
data class Config(var params: Params, var opts: List<Option>) : Parcelable, Serializable, Comparable<Config> { data class Config(
var params: Params,
var opts: List<Option>
) : Parcelable, Serializable, Comparable<Config> {
companion object { companion object {
@JvmStatic @JvmStatic
private val serialVersionUID: Long = 1 private val serialVersionUID: Long = 1
@ -37,7 +40,8 @@ data class Config(var params: Params, var opts: List<Option>) : Parcelable, Seri
constructor(source: Parcel) : this( constructor(source: Parcel) : this(
source.readParcelable<Params>(Params::class.java.classLoader), source.readParcelable<Params>(Params::class.java.classLoader),
source.createTypedArrayList(Option.CREATOR)) source.createTypedArrayList(Option.CREATOR)
)
override fun compareTo(other: Config): Int = params.name.compareTo(other.params.name) override fun compareTo(other: Config): Int = params.name.compareTo(other.params.name)

View file

@ -1,7 +1,7 @@
/* /*
* Configurations.kt * Configurations.kt
* *
* Copyright 2016-2018 Erik C. Thauvin (erik@thauvin.net) * Copyright 2016-2019 Erik C. Thauvin (erik@thauvin.net)
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View file

@ -1,7 +1,7 @@
/* /*
* Field.kt * Field.kt
* *
* Copyright 2016-2018 Erik C. Thauvin (erik@thauvin.net) * Copyright 2016-2019 Erik C. Thauvin (erik@thauvin.net)
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -54,7 +54,8 @@ data class Field(
source.readInt(), source.readInt(),
source.readInt(), source.readInt(),
source.readInt(), source.readInt(),
source.readInt()) source.readInt()
)
override fun describeContents() = 0 override fun describeContents() = 0

View file

@ -1,7 +1,7 @@
/* /*
* Option.kt * Option.kt
* *
* Copyright 2016-2018 Erik C. Thauvin (erik@thauvin.net) * Copyright 2016-2019 Erik C. Thauvin (erik@thauvin.net)
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -46,7 +46,8 @@ data class Option(
source.createTypedArrayList(Field.CREATOR), source.createTypedArrayList(Field.CREATOR),
1 == source.readInt(), 1 == source.readInt(),
1 == source.readInt(), 1 == source.readInt(),
source.readString()) source.readString()
)
override fun compareTo(other: Option): Int = title.compareTo(other.title) override fun compareTo(other: Option): Int = title.compareTo(other.title)

View file

@ -1,7 +1,7 @@
/* /*
* Params.kt * Params.kt
* *
* Copyright 2016-2018 Erik C. Thauvin (erik@thauvin.net) * Copyright 2016-2019 Erik C. Thauvin (erik@thauvin.net)
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -54,7 +54,8 @@ data class Params(
source.readString(), source.readString(),
source.readString(), source.readString(),
source.readString(), source.readString(),
source.readString()) source.readString()
)
override fun describeContents() = 0 override fun describeContents() = 0

View file

@ -1,7 +1,7 @@
/* /*
* CrashEmail.kt * CrashEmail.kt
* *
* Copyright 2016-2018 Erik C. Thauvin (erik@thauvin.net) * Copyright 2016-2019 Erik C. Thauvin (erik@thauvin.net)
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -35,8 +35,10 @@ class CrashEmail(private val config: ACRAConfiguration) : ReportSender {
@Throws(ReportSenderException::class) @Throws(ReportSenderException::class)
override fun send(context: Context, errorContent: CrashReportData) { override fun send(context: Context, errorContent: CrashReportData) {
val subject = context.getString(R.string.crash_report_subject, val subject = context.getString(
context.getString(R.string.app_name)) R.string.crash_report_subject,
context.getString(R.string.app_name)
)
val body = buildBody(errorContent) val body = buildBody(errorContent)
val emailIntent = Intent(android.content.Intent.ACTION_SENDTO) val emailIntent = Intent(android.content.Intent.ACTION_SENDTO)

View file

@ -1,7 +1,7 @@
/* /*
* CrashEmailFactory.kt * CrashEmailFactory.kt
* *
* Copyright 2016-2018 Erik C. Thauvin (erik@thauvin.net) * Copyright 2016-2019 Erik C. Thauvin (erik@thauvin.net)
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View file

@ -1,7 +1,7 @@
/* /*
* CrashReportActivity.kt * CrashReportActivity.kt
* *
* Copyright 2016-2018 Erik C. Thauvin (erik@thauvin.net) * Copyright 2016-2019 Erik C. Thauvin (erik@thauvin.net)
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -32,7 +32,7 @@ class CrashReportActivity : BaseCrashReportDialog(), DialogInterface.OnDismissLi
private var comment: EditText? = null private var comment: EditText? = null
companion object { companion object {
private val STATE_USER_COMMENT = "comment" private const val STATE_USER_COMMENT = "comment"
} }
override fun init(savedInstanceState: Bundle?) { override fun init(savedInstanceState: Bundle?) {

View file

@ -1,7 +1,7 @@
/* /*
* Dtmf.kt * Dtmf.kt
* *
* Copyright 2016-2018 Erik C. Thauvin (erik@thauvin.net) * Copyright 2016-2019 Erik C. Thauvin (erik@thauvin.net)
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -24,12 +24,12 @@ import java.util.ArrayList
class Dtmf { class Dtmf {
companion object { companion object {
val DTMF_MASTER = "[MASTER]" const val DTMF_MASTER = "[MASTER]"
val DTMF_FIELD = "[FIELD:%1\$d]" const val DTMF_FIELD = "[FIELD:%1\$d]"
val DKS = "dks" const val DKS = "dks"
val LINEAR = "linear" const val LINEAR = "linear"
val DKS_EXTRAS = " " const val DKS_EXTRAS = " "
val LINEAR_EXTRAS = ", -." const val LINEAR_EXTRAS = ", -."
private fun dksAlphaToDigits(text: String, ack: String): String { private fun dksAlphaToDigits(text: String, ack: String): String {
val result = StringBuffer() val result = StringBuffer()
@ -159,14 +159,18 @@ class Dtmf {
val replace = arrayListOf(Pair(DTMF_MASTER, master)) val replace = arrayListOf(Pair(DTMF_MASTER, master))
fields.forEachIndexed { i, field -> fields.forEachIndexed { i, field ->
replace.add(Pair(DTMF_FIELD.format(i + 1), replace.add(
Pair(
DTMF_FIELD.format(i + 1),
if (option.fields[i]!!.alpha && type.isDKS()) { if (option.fields[i]!!.alpha && type.isDKS()) {
dksAlphaToDigits(field.text.toString(), ack) dksAlphaToDigits(field.text.toString(), ack)
} else if (option.fields[i]!!.alpha && type.isLinear()) { } else if (option.fields[i]!!.alpha && type.isLinear()) {
linearAlphaToDigits(field.text.toString()) linearAlphaToDigits(field.text.toString())
} else { } else {
field.text.toString() field.text.toString()
})) }
)
)
} }
return option.dtmf.replaceAll(replace.toTypedArray()) return option.dtmf.replaceAll(replace.toTypedArray())

View file

@ -6,7 +6,7 @@
<item> <item>
<bitmap <bitmap
android:gravity="center" android:gravity="center"
android:src="@drawable/splash"/> android:src="@drawable/splash" />
</item> </item>
</layer-list> </layer-list>

View file

@ -7,10 +7,10 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" android:orientation="vertical"
android:paddingBottom="24dp"
android:paddingLeft="24dp" android:paddingLeft="24dp"
android:paddingTop="20dp"
android:paddingRight="24dp" android:paddingRight="24dp"
android:paddingTop="20dp"> android:paddingBottom="24dp">
<TextView <TextView
android:id="@android:id/text1" android:id="@android:id/text1"

View file

@ -1,5 +1,9 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<full-backup-content> <full-backup-content>
<include domain="file" path="configurations.dat"/> <include
<include domain="file" path="config.dat"/> domain="file"
path="configurations.dat" />
<include
domain="file"
path="config.dat" />
</full-backup-content> </full-backup-content>

View file

@ -1,13 +1,13 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules. // Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript { buildscript {
ext.kotlin_version = '1.3.0' ext.kotlin_version = '1.3.41'
repositories { repositories {
jcenter() jcenter()
google() google()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:3.2.1' classpath 'com.android.tools.build:gradle:3.5.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong // NOTE: Do not place your application dependencies here; they belong

View file

@ -1,6 +1,6 @@
#Sun Nov 04 14:30:01 PST 2018 #Wed Sep 25 10:52:41 PDT 2019
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip