Added ktlint.
This commit is contained in:
parent
1ea0e84239
commit
4c314683c7
19 changed files with 325 additions and 259 deletions
5
.idea/codeStyles/codeStyleConfig.xml
generated
Normal file
5
.idea/codeStyles/codeStyleConfig.xml
generated
Normal file
|
@ -0,0 +1,5 @@
|
|||
<component name="ProjectCodeStyleConfiguration">
|
||||
<state>
|
||||
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Erik's Code Style" />
|
||||
</state>
|
||||
</component>
|
|
@ -1,3 +1,7 @@
|
|||
plugins {
|
||||
id "org.jlleitschuh.gradle.ktlint" version "6.2.1"
|
||||
}
|
||||
|
||||
//noinspection GradleCompatible
|
||||
apply plugin: 'com.android.application'
|
||||
apply plugin: 'kotlin-android'
|
||||
|
@ -72,4 +76,4 @@ repositories {
|
|||
|
||||
kapt {
|
||||
//generateStubs = true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,12 +25,10 @@ import org.acra.ACRA
|
|||
import org.acra.ReportingInteractionMode
|
||||
import org.acra.annotation.ReportsCrashes
|
||||
|
||||
|
||||
@ReportsCrashes(mailTo = "erik@thauvin.net",
|
||||
mode = ReportingInteractionMode.DIALOG,
|
||||
reportSenderFactoryClasses = arrayOf(CrashEmailFactory::class),
|
||||
reportDialogClass = CrashReportActivity::class)
|
||||
|
||||
mode = ReportingInteractionMode.DIALOG,
|
||||
reportSenderFactoryClasses = arrayOf(CrashEmailFactory::class),
|
||||
reportDialogClass = CrashReportActivity::class)
|
||||
open class App : Application() {
|
||||
override fun attachBaseContext(base: Context) {
|
||||
super.attachBaseContext(base)
|
||||
|
|
|
@ -27,7 +27,11 @@ import android.graphics.Typeface
|
|||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.support.v7.app.AppCompatActivity
|
||||
import android.text.*
|
||||
import android.text.Html
|
||||
import android.text.InputFilter
|
||||
import android.text.InputType
|
||||
import android.text.Spanned
|
||||
import android.text.TextUtils
|
||||
import android.util.TypedValue
|
||||
import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
|
@ -45,9 +49,22 @@ import net.thauvin.erik.android.tesremoteprogrammer.models.Configurations
|
|||
import net.thauvin.erik.android.tesremoteprogrammer.util.Dtmf
|
||||
import net.thauvin.erik.android.tesremoteprogrammer.util.isDKS
|
||||
import net.thauvin.erik.android.tesremoteprogrammer.util.isDigits
|
||||
import org.jetbrains.anko.*
|
||||
import org.jetbrains.anko.AnkoLogger
|
||||
import org.jetbrains.anko.alert
|
||||
import org.jetbrains.anko.bottomPadding
|
||||
import org.jetbrains.anko.cancelButton
|
||||
import org.jetbrains.anko.design.textInputEditText
|
||||
import org.jetbrains.anko.design.textInputLayout
|
||||
import org.jetbrains.anko.dip
|
||||
import org.jetbrains.anko.horizontalPadding
|
||||
import org.jetbrains.anko.info
|
||||
import org.jetbrains.anko.listView
|
||||
import org.jetbrains.anko.padding
|
||||
import org.jetbrains.anko.singleLine
|
||||
import org.jetbrains.anko.startActivity
|
||||
import org.jetbrains.anko.textView
|
||||
import org.jetbrains.anko.topPadding
|
||||
import org.jetbrains.anko.verticalLayout
|
||||
import permissions.dispatcher.NeedsPermission
|
||||
import permissions.dispatcher.RuntimePermissions
|
||||
import java.io.FileNotFoundException
|
||||
|
@ -55,7 +72,9 @@ import java.io.InputStreamReader
|
|||
import java.io.ObjectInputStream
|
||||
import java.io.ObjectOutputStream
|
||||
import java.text.DateFormat
|
||||
import java.util.*
|
||||
import java.util.ArrayList
|
||||
import java.util.Date
|
||||
import java.util.Locale
|
||||
|
||||
@RuntimePermissions
|
||||
class MainActivity : AppCompatActivity(), AnkoLogger {
|
||||
|
@ -64,13 +83,13 @@ class MainActivity : AppCompatActivity(), AnkoLogger {
|
|||
private val configurationsData = "configurations.dat"
|
||||
private val currentConfigData = "config.dat"
|
||||
private val defaultConfigurations = listOf(
|
||||
R.raw.dks_1802,
|
||||
R.raw.dks_1802_epd,
|
||||
R.raw.dks_1812,
|
||||
R.raw.dks_1819,
|
||||
R.raw.linear_ae_100,
|
||||
R.raw.linear_ae_500,
|
||||
R.raw.dks_1803_1808_1810)
|
||||
R.raw.dks_1802,
|
||||
R.raw.dks_1802_epd,
|
||||
R.raw.dks_1812,
|
||||
R.raw.dks_1819,
|
||||
R.raw.linear_ae_100,
|
||||
R.raw.linear_ae_500,
|
||||
R.raw.dks_1803_1808_1810)
|
||||
private val readRequestCode = 42
|
||||
|
||||
companion object {
|
||||
|
@ -97,7 +116,7 @@ class MainActivity : AppCompatActivity(), AnkoLogger {
|
|||
|
||||
defaultConfigurations.forEach {
|
||||
config = Gson().fromJson(InputStreamReader(resources.openRawResource(it)),
|
||||
Config::class.java)
|
||||
Config::class.java)
|
||||
|
||||
if (BuildConfig.DEBUG) {
|
||||
val errors = StringBuilder()
|
||||
|
@ -126,7 +145,7 @@ class MainActivity : AppCompatActivity(), AnkoLogger {
|
|||
|
||||
extraTitle = "Last Update"
|
||||
extra = DateFormat.getDateInstance(DateFormat.LONG, Locale.getDefault()).format(
|
||||
Date(BuildConfig.TIMESTAMP)).toString()
|
||||
Date(BuildConfig.TIMESTAMP)).toString()
|
||||
|
||||
emailAddress = "erik@thauvin.net"
|
||||
emailSubject = "${getString(R.string.app_name)} ${BuildConfig.VERSION_NAME} Support"
|
||||
|
@ -154,7 +173,7 @@ class MainActivity : AppCompatActivity(), AnkoLogger {
|
|||
|
||||
val tmp: Config? = try {
|
||||
Gson().fromJson(InputStreamReader(contentResolver.openInputStream(intent.data)),
|
||||
Config::class.java)
|
||||
Config::class.java)
|
||||
} catch (jse: JsonSyntaxException) {
|
||||
val cause = jse.cause
|
||||
if (cause != null) {
|
||||
|
@ -291,8 +310,8 @@ class MainActivity : AppCompatActivity(), AnkoLogger {
|
|||
if (validateFields(fields)) {
|
||||
saveConfig()
|
||||
startActivity<ProgrammingActivity>(
|
||||
"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.Params" to config.params,
|
||||
"net.thauvin.erik.android.tesremoteprogrammer.models.Option" to opts[position])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -340,16 +359,17 @@ class MainActivity : AppCompatActivity(), AnkoLogger {
|
|||
}
|
||||
|
||||
alert.show()
|
||||
|
||||
}
|
||||
}
|
||||
return super.onOptionsItemSelected(item)
|
||||
}
|
||||
|
||||
@SuppressLint("NeedOnRequestPermissionsResult")
|
||||
override fun onRequestPermissionsResult(requestCode: Int,
|
||||
permissions: Array<out String>,
|
||||
grantResults: IntArray) {
|
||||
override fun onRequestPermissionsResult(
|
||||
requestCode: Int,
|
||||
permissions: Array<out String>,
|
||||
grantResults: IntArray
|
||||
) {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
|
||||
onRequestPermissionsResult(requestCode, grantResults)
|
||||
}
|
||||
|
@ -365,9 +385,9 @@ class MainActivity : AppCompatActivity(), AnkoLogger {
|
|||
}
|
||||
|
||||
private fun saveConfigurations(confs: Configurations) =
|
||||
ObjectOutputStream(openFileOutput(configurationsData, Context.MODE_PRIVATE)).use {
|
||||
it.writeObject(confs)
|
||||
}
|
||||
ObjectOutputStream(openFileOutput(configurationsData, Context.MODE_PRIVATE)).use {
|
||||
it.writeObject(confs)
|
||||
}
|
||||
|
||||
private fun saveConfig(backup: Boolean = true) {
|
||||
if (backup) {
|
||||
|
@ -397,7 +417,6 @@ class MainActivity : AppCompatActivity(), AnkoLogger {
|
|||
errors.append(getString(R.string.validate_missing_param, "type"))
|
||||
} else if (!Dtmf.isValidType(type)) {
|
||||
errors.append(getString(R.string.validate_invalid_param, "type"))
|
||||
|
||||
}
|
||||
|
||||
// size
|
||||
|
@ -426,49 +445,49 @@ class MainActivity : AppCompatActivity(), AnkoLogger {
|
|||
// title
|
||||
if (title.isBlank()) {
|
||||
errors.append(getString(
|
||||
R.string.validate_missing_opts_prop,
|
||||
i + 1,
|
||||
"title"))
|
||||
R.string.validate_missing_opts_prop,
|
||||
i + 1,
|
||||
"title"))
|
||||
}
|
||||
|
||||
// nosteps/nodial
|
||||
if (nosteps && nodial) {
|
||||
errors.append(getString(
|
||||
R.string.validate_invalid_option,
|
||||
i + 1,
|
||||
"nodial/nosteps"))
|
||||
R.string.validate_invalid_option,
|
||||
i + 1,
|
||||
"nodial/nosteps"))
|
||||
}
|
||||
|
||||
// dtmf
|
||||
if (dtmf.isBlank()) {
|
||||
errors.append(getString(
|
||||
R.string.validate_missing_opts_prop,
|
||||
i + 1,
|
||||
"dtmf"))
|
||||
R.string.validate_missing_opts_prop,
|
||||
i + 1,
|
||||
"dtmf"))
|
||||
} else if (!nodial && fields.isEmpty()) { // fields missing
|
||||
errors.append(getString(
|
||||
R.string.validate_missing_opts_prop,
|
||||
i + 1,
|
||||
"fields"))
|
||||
R.string.validate_missing_opts_prop,
|
||||
i + 1,
|
||||
"fields"))
|
||||
} else {
|
||||
val blank = "\\0"
|
||||
val mock = Dtmf.mock(option, blank)
|
||||
|
||||
if (!mock.contains(MainActivity.PAUSE)) { // no pause
|
||||
errors.append(getString(
|
||||
R.string.validate_invalid_opts_prop,
|
||||
i + 1,
|
||||
"dtmf",
|
||||
getString(R.string.validate_dtmf_nopause)))
|
||||
R.string.validate_invalid_opts_prop,
|
||||
i + 1,
|
||||
"dtmf",
|
||||
getString(R.string.validate_dtmf_nopause)))
|
||||
}
|
||||
|
||||
if (!Dtmf.validate(mock,
|
||||
"${MainActivity.PAUSE}${params.ack}${params.alt}$blank", nodial)) {
|
||||
"${MainActivity.PAUSE}${params.ack}${params.alt}$blank", nodial)) {
|
||||
errors.append(getString(
|
||||
R.string.validate_invalid_opts_prop,
|
||||
i + 1,
|
||||
"dtmf",
|
||||
mock.replace(blank, "✓")))
|
||||
R.string.validate_invalid_opts_prop,
|
||||
i + 1,
|
||||
"dtmf",
|
||||
mock.replace(blank, "✓")))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -476,78 +495,78 @@ class MainActivity : AppCompatActivity(), AnkoLogger {
|
|||
fields.forEachIndexed { j, field ->
|
||||
if (field == null) {
|
||||
errors.append(getString(
|
||||
R.string.validate_syntax_error,
|
||||
"opts[${i + 1}], field[$j]"))
|
||||
R.string.validate_syntax_error,
|
||||
"opts[${i + 1}], field[$j]"))
|
||||
} else {
|
||||
with(field) {
|
||||
// size
|
||||
if (size <= 0) {
|
||||
errors.append(getString(
|
||||
R.string.validate_invalid_field_prop,
|
||||
i + 1,
|
||||
j + 1,
|
||||
resources.getQuantityString(R.plurals.error_prop, 1),
|
||||
"size=$size"))
|
||||
R.string.validate_invalid_field_prop,
|
||||
i + 1,
|
||||
j + 1,
|
||||
resources.getQuantityString(R.plurals.error_prop, 1),
|
||||
"size=$size"))
|
||||
}
|
||||
|
||||
// digits
|
||||
if (digits.isNotBlank() && !digits.isDigits()) {
|
||||
errors.append(getString(
|
||||
R.string.validate_invalid_field_prop,
|
||||
i + 1,
|
||||
j + 1,
|
||||
resources.getQuantityString(R.plurals.error_prop, 1),
|
||||
"digits='$digits'"))
|
||||
R.string.validate_invalid_field_prop,
|
||||
i + 1,
|
||||
j + 1,
|
||||
resources.getQuantityString(R.plurals.error_prop, 1),
|
||||
"digits='$digits'"))
|
||||
}
|
||||
|
||||
// minSize
|
||||
if (minSize >= 0 && minSize > size) {
|
||||
errors.append(getString(
|
||||
R.string.validate_invalid_field_prop,
|
||||
i + 1,
|
||||
j + 1,
|
||||
resources.getQuantityString(R.plurals.error_prop, 2),
|
||||
"minSize=$minSize > size=$size"))
|
||||
R.string.validate_invalid_field_prop,
|
||||
i + 1,
|
||||
j + 1,
|
||||
resources.getQuantityString(R.plurals.error_prop, 2),
|
||||
"minSize=$minSize > size=$size"))
|
||||
}
|
||||
|
||||
// numeric fields only
|
||||
if (!alpha) {
|
||||
if (minSize == 0) {
|
||||
errors.append(getString(
|
||||
R.string.validate_invalid_field_prop,
|
||||
i + 1,
|
||||
j + 1,
|
||||
resources.getQuantityString(R.plurals.error_prop, 1),
|
||||
"minSize=$minSize"))
|
||||
R.string.validate_invalid_field_prop,
|
||||
i + 1,
|
||||
j + 1,
|
||||
resources.getQuantityString(R.plurals.error_prop, 1),
|
||||
"minSize=$minSize"))
|
||||
}
|
||||
|
||||
// min/max
|
||||
if (min >= 0 || max >= 0) {
|
||||
if (max < 1) {
|
||||
errors.append(getString(
|
||||
R.string.validate_invalid_field_prop,
|
||||
i + 1,
|
||||
j + 1,
|
||||
resources.getQuantityString(R.plurals.error_prop, 1),
|
||||
"max=$max"))
|
||||
R.string.validate_invalid_field_prop,
|
||||
i + 1,
|
||||
j + 1,
|
||||
resources.getQuantityString(R.plurals.error_prop, 1),
|
||||
"max=$max"))
|
||||
}
|
||||
|
||||
if (min < 0) {
|
||||
errors.append(getString(
|
||||
R.string.validate_invalid_field_prop,
|
||||
i + 1,
|
||||
j + 1,
|
||||
resources.getQuantityString(R.plurals.error_prop, 1),
|
||||
"min=$min"))
|
||||
R.string.validate_invalid_field_prop,
|
||||
i + 1,
|
||||
j + 1,
|
||||
resources.getQuantityString(R.plurals.error_prop, 1),
|
||||
"min=$min"))
|
||||
}
|
||||
|
||||
if (min > max) {
|
||||
errors.append(getString(
|
||||
R.string.validate_invalid_field_prop,
|
||||
i + 1,
|
||||
j + 1,
|
||||
resources.getQuantityString(R.plurals.error_prop, 2),
|
||||
"min=$min > max=$max"))
|
||||
R.string.validate_invalid_field_prop,
|
||||
i + 1,
|
||||
j + 1,
|
||||
resources.getQuantityString(R.plurals.error_prop, 2),
|
||||
"min=$min > max=$max"))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -557,11 +576,11 @@ class MainActivity : AppCompatActivity(), AnkoLogger {
|
|||
if (min >= 0 && minSize > 0) {
|
||||
if (min.toString().length != minSize) {
|
||||
errors.append(getString(
|
||||
R.string.validate_invalid_field_prop,
|
||||
i + 1,
|
||||
j + 1,
|
||||
resources.getQuantityString(R.plurals.error_prop, 2),
|
||||
"minSize=$minSize/min=$min"))
|
||||
R.string.validate_invalid_field_prop,
|
||||
i + 1,
|
||||
j + 1,
|
||||
resources.getQuantityString(R.plurals.error_prop, 2),
|
||||
"minSize=$minSize/min=$min"))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -569,11 +588,11 @@ class MainActivity : AppCompatActivity(), AnkoLogger {
|
|||
if (size > 0 && max > 0) {
|
||||
if (max.toString().length != size) {
|
||||
errors.append(getString(
|
||||
R.string.validate_invalid_field_prop,
|
||||
i + 1,
|
||||
j + 1,
|
||||
resources.getQuantityString(R.plurals.error_prop, 2),
|
||||
"size=$size/max=$max"))
|
||||
R.string.validate_invalid_field_prop,
|
||||
i + 1,
|
||||
j + 1,
|
||||
resources.getQuantityString(R.plurals.error_prop, 2),
|
||||
"size=$size/max=$max"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -582,9 +601,9 @@ class MainActivity : AppCompatActivity(), AnkoLogger {
|
|||
// unused fields
|
||||
if (!dtmf.contains(Dtmf.DTMF_FIELD.format(j + 1))) {
|
||||
errors.append(getString(
|
||||
R.string.validate_unused_field,
|
||||
i + 1,
|
||||
j + 1))
|
||||
R.string.validate_unused_field,
|
||||
i + 1,
|
||||
j + 1))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -608,7 +627,7 @@ class MainActivity : AppCompatActivity(), AnkoLogger {
|
|||
isValid = false
|
||||
} else if (second > 0 && first.text.length != second) {
|
||||
first.error = getString(R.string.error_invalid_size, second,
|
||||
resources.getQuantityString(R.plurals.error_digit, second), "")
|
||||
resources.getQuantityString(R.plurals.error_digit, second), "")
|
||||
isValid = false
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,7 +32,9 @@ import android.text.SpannableString
|
|||
import android.text.TextUtils
|
||||
import android.text.style.ImageSpan
|
||||
import android.util.TypedValue
|
||||
import android.view.Gravity.*
|
||||
import android.view.Gravity.BOTTOM
|
||||
import android.view.Gravity.END
|
||||
import android.view.Gravity.START
|
||||
import android.view.ViewManager
|
||||
import android.view.inputmethod.EditorInfo
|
||||
import android.view.inputmethod.InputMethodManager
|
||||
|
@ -47,16 +49,29 @@ import net.thauvin.erik.android.tesremoteprogrammer.util.Dtmf
|
|||
import net.thauvin.erik.android.tesremoteprogrammer.util.isDKS
|
||||
import net.thauvin.erik.android.tesremoteprogrammer.util.isLinear
|
||||
import net.thauvin.erik.android.tesremoteprogrammer.widget.ScrollAwareFABBehavior
|
||||
import org.jetbrains.anko.*
|
||||
import org.jetbrains.anko.AnkoLogger
|
||||
import org.jetbrains.anko.bottomPadding
|
||||
import org.jetbrains.anko.custom.ankoView
|
||||
import org.jetbrains.anko.design.coordinatorLayout
|
||||
import org.jetbrains.anko.design.floatingActionButton
|
||||
import org.jetbrains.anko.design.textInputEditText
|
||||
import org.jetbrains.anko.design.textInputLayout
|
||||
import org.jetbrains.anko.dip
|
||||
import org.jetbrains.anko.horizontalPadding
|
||||
import org.jetbrains.anko.imageResource
|
||||
import org.jetbrains.anko.info
|
||||
import org.jetbrains.anko.makeCall
|
||||
import org.jetbrains.anko.matchParent
|
||||
import org.jetbrains.anko.padding
|
||||
import org.jetbrains.anko.singleLine
|
||||
import org.jetbrains.anko.startActivity
|
||||
import org.jetbrains.anko.support.v4.nestedScrollView
|
||||
import org.jetbrains.anko.topPadding
|
||||
import org.jetbrains.anko.verticalLayout
|
||||
import org.jetbrains.anko.wrapContent
|
||||
import permissions.dispatcher.NeedsPermission
|
||||
import permissions.dispatcher.RuntimePermissions
|
||||
import java.util.*
|
||||
import java.util.ArrayList
|
||||
|
||||
@RuntimePermissions
|
||||
class ProgrammingActivity : AppCompatActivity(), AnkoLogger {
|
||||
|
@ -100,7 +115,6 @@ class ProgrammingActivity : AppCompatActivity(), AnkoLogger {
|
|||
typeface = Typeface.create(Typeface.DEFAULT, Typeface.ITALIC)
|
||||
freezesText = true
|
||||
}.lparams(width = matchParent, height = matchParent)
|
||||
|
||||
} else {
|
||||
val it = option.fields.iterator()
|
||||
while (it.hasNext()) {
|
||||
|
@ -129,11 +143,11 @@ class ProgrammingActivity : AppCompatActivity(), AnkoLogger {
|
|||
inputFilters.add(NumberFilter(field.digits, if (field.alt) params.alt else empty))
|
||||
if (field.max != -1 && field.min != -1) {
|
||||
inputFilters.add(
|
||||
MinMaxFilter(
|
||||
field.min,
|
||||
field.max,
|
||||
field.size,
|
||||
params.type.isDKS() || field.zeros))
|
||||
MinMaxFilter(
|
||||
field.min,
|
||||
field.max,
|
||||
field.size,
|
||||
params.type.isDKS() || field.zeros))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -203,15 +217,15 @@ class ProgrammingActivity : AppCompatActivity(), AnkoLogger {
|
|||
}
|
||||
|
||||
startActivity<StepsActivity>(
|
||||
StepsActivity.EXTRA_STEPS to "$begin${dtmf.replace(MainActivity.QUOTE, empty)}$end".split(MainActivity.PAUSE))
|
||||
StepsActivity.EXTRA_STEPS to "$begin${dtmf.replace(MainActivity.QUOTE, empty)}$end".split(MainActivity.PAUSE))
|
||||
} else {
|
||||
Snackbar.make(this@coordinatorLayout,
|
||||
getString(R.string.error_invalid_dtmf, dtmf),
|
||||
Snackbar.LENGTH_LONG).show()
|
||||
getString(R.string.error_invalid_dtmf, dtmf),
|
||||
Snackbar.LENGTH_LONG).show()
|
||||
}
|
||||
} else {
|
||||
Snackbar.make(this@coordinatorLayout, R.string.error_invalid_field,
|
||||
Snackbar.LENGTH_LONG).show()
|
||||
Snackbar.LENGTH_LONG).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -234,12 +248,12 @@ class ProgrammingActivity : AppCompatActivity(), AnkoLogger {
|
|||
callWithPermissionCheck(params.phone, dtmf)
|
||||
} else {
|
||||
Snackbar.make(this@coordinatorLayout,
|
||||
getString(R.string.error_invalid_dtmf, dtmf),
|
||||
Snackbar.LENGTH_LONG).show()
|
||||
getString(R.string.error_invalid_dtmf, dtmf),
|
||||
Snackbar.LENGTH_LONG).show()
|
||||
}
|
||||
} else {
|
||||
Snackbar.make(this@coordinatorLayout, R.string.error_invalid_field,
|
||||
Snackbar.LENGTH_LONG).show()
|
||||
Snackbar.LENGTH_LONG).show()
|
||||
}
|
||||
} else {
|
||||
val text = SpannableString(getString(R.string.error_invalid_field_for_call) + " ")
|
||||
|
@ -252,9 +266,11 @@ class ProgrammingActivity : AppCompatActivity(), AnkoLogger {
|
|||
}
|
||||
|
||||
@SuppressLint("NeedOnRequestPermissionsResult")
|
||||
override fun onRequestPermissionsResult(requestCode: Int,
|
||||
permissions: Array<out String>,
|
||||
grantResults: IntArray) {
|
||||
override fun onRequestPermissionsResult(
|
||||
requestCode: Int,
|
||||
permissions: Array<out String>,
|
||||
grantResults: IntArray
|
||||
) {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
|
||||
onRequestPermissionsResult(requestCode, grantResults)
|
||||
}
|
||||
|
@ -295,16 +311,16 @@ class ProgrammingActivity : AppCompatActivity(), AnkoLogger {
|
|||
} else if (!validateSize(v.length(), if ((!type.isDKS() && !zeros) && min >= 0) min.toString().length else minSize, size)) {
|
||||
if (minSize > 0) {
|
||||
v.error = getString(
|
||||
R.string.error_invalid_size,
|
||||
minSize,
|
||||
resources.getQuantityString(R.plurals.error_digit, minSize),
|
||||
getString(R.string.error_minimum))
|
||||
R.string.error_invalid_size,
|
||||
minSize,
|
||||
resources.getQuantityString(R.plurals.error_digit, minSize),
|
||||
getString(R.string.error_minimum))
|
||||
} else {
|
||||
v.error = getString(
|
||||
R.string.error_invalid_size,
|
||||
size,
|
||||
resources.getQuantityString(R.plurals.error_digit, size),
|
||||
empty)
|
||||
R.string.error_invalid_size,
|
||||
size,
|
||||
resources.getQuantityString(R.plurals.error_digit, size),
|
||||
empty)
|
||||
}
|
||||
isValid = false
|
||||
} else if (min >= 0 && max > 0) {
|
||||
|
|
|
@ -22,8 +22,9 @@ import android.app.FragmentManager
|
|||
import android.os.Bundle
|
||||
import android.support.v13.app.FragmentStatePagerAdapter
|
||||
import android.support.v4.app.FragmentActivity
|
||||
import kotlinx.android.synthetic.main.activity_steps.*
|
||||
import java.util.*
|
||||
import kotlinx.android.synthetic.main.activity_steps.indicator
|
||||
import kotlinx.android.synthetic.main.activity_steps.pager
|
||||
import java.util.ArrayList
|
||||
|
||||
class StepsActivity : FragmentActivity() {
|
||||
companion object {
|
||||
|
@ -39,8 +40,10 @@ class StepsActivity : FragmentActivity() {
|
|||
indicator.fades = false
|
||||
}
|
||||
|
||||
private inner class StepsAdapter(fm: FragmentManager,
|
||||
steps: ArrayList<String>) : FragmentStatePagerAdapter(fm) {
|
||||
private inner class StepsAdapter(
|
||||
fm: FragmentManager,
|
||||
steps: ArrayList<String>
|
||||
) : FragmentStatePagerAdapter(fm) {
|
||||
private val steps = ArrayList<String>(steps)
|
||||
|
||||
override fun getItem(position: Int): Fragment = StepsFragment.create(position, steps)
|
||||
|
|
|
@ -22,8 +22,9 @@ import android.os.Bundle
|
|||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import kotlinx.android.synthetic.main.fragment_steps.*
|
||||
import java.util.*
|
||||
import kotlinx.android.synthetic.main.fragment_steps.frag_steps
|
||||
import kotlinx.android.synthetic.main.fragment_steps.frag_steps_title
|
||||
import java.util.ArrayList
|
||||
|
||||
class StepsFragment : Fragment() {
|
||||
private var pageNumber: Int = 0
|
||||
|
@ -51,9 +52,11 @@ class StepsFragment : Fragment() {
|
|||
pageNumber = arguments.getInt(ARG_PAGE)
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?): View? =
|
||||
inflater.inflate(R.layout.fragment_steps, container, false) as ViewGroup
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? = inflater.inflate(R.layout.fragment_steps, container, false) as ViewGroup
|
||||
|
||||
override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
|
|
@ -22,13 +22,14 @@ import android.text.SpannableStringBuilder
|
|||
import android.text.Spanned
|
||||
|
||||
class AlphaFilter(private val extras: String) : InputFilter {
|
||||
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? {
|
||||
if (source is SpannableStringBuilder) {
|
||||
for (i in end - 1 downTo start) {
|
||||
val c = source[i]
|
||||
|
@ -40,9 +41,9 @@ class AlphaFilter(private val extras: String) : InputFilter {
|
|||
} else {
|
||||
val sb = StringBuilder()
|
||||
(start until end)
|
||||
.map { source[it] }
|
||||
.filter { it.isLetterOrDigit() || extras.contains(it) }
|
||||
.forEach { sb.append(it) }
|
||||
.map { source[it] }
|
||||
.filter { it.isLetterOrDigit() || extras.contains(it) }
|
||||
.forEach { sb.append(it) }
|
||||
return sb.toString()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,13 +27,14 @@ class NumberFilter(allowed: String, alt: String) : InputFilter, AnkoLogger {
|
|||
private val allowed: String
|
||||
private val digits = "0123456789"
|
||||
|
||||
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? {
|
||||
if (source is SpannableStringBuilder) {
|
||||
for (i in end - 1 downTo start) {
|
||||
val c = source[i]
|
||||
|
@ -45,9 +46,9 @@ class NumberFilter(allowed: String, alt: String) : InputFilter, AnkoLogger {
|
|||
} else {
|
||||
val sb = StringBuilder()
|
||||
(start until end)
|
||||
.map { source[it] }
|
||||
.filter { allowed.contains(it) }
|
||||
.forEach { sb.append(it.toUpperCase()) }
|
||||
.map { source[it] }
|
||||
.filter { allowed.contains(it) }
|
||||
.forEach { sb.append(it.toUpperCase()) }
|
||||
return sb.toString()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,9 +23,11 @@ import java.io.Serializable
|
|||
|
||||
data class Config(var params: Params, var opts: List<Option>) : Parcelable, Serializable, Comparable<Config> {
|
||||
companion object {
|
||||
private @JvmStatic val serialVersionUID: Long = 1
|
||||
@JvmStatic
|
||||
private val serialVersionUID: Long = 1
|
||||
|
||||
@JvmField val CREATOR: Parcelable.Creator<Config> = object : Parcelable.Creator<Config> {
|
||||
@JvmField
|
||||
val CREATOR: Parcelable.Creator<Config> = object : Parcelable.Creator<Config> {
|
||||
override fun createFromParcel(source: Parcel): Config = Config(source)
|
||||
override fun newArray(size: Int): Array<Config?> = arrayOfNulls(size)
|
||||
}
|
||||
|
@ -34,8 +36,8 @@ data class Config(var params: Params, var opts: List<Option>) : Parcelable, Seri
|
|||
constructor() : this(Params(), emptyList<Option>())
|
||||
|
||||
constructor(source: Parcel) : this(
|
||||
source.readParcelable<Params>(Params::class.java.classLoader),
|
||||
source.createTypedArrayList(Option.CREATOR))
|
||||
source.readParcelable<Params>(Params::class.java.classLoader),
|
||||
source.createTypedArrayList(Option.CREATOR))
|
||||
|
||||
override fun compareTo(other: Config): Int = params.name.compareTo(other.params.name)
|
||||
|
||||
|
|
|
@ -18,11 +18,12 @@
|
|||
package net.thauvin.erik.android.tesremoteprogrammer.models
|
||||
|
||||
import java.io.Serializable
|
||||
import java.util.*
|
||||
import java.util.HashMap
|
||||
|
||||
class Configurations : Serializable {
|
||||
companion object {
|
||||
private @JvmStatic val serialVersionUID: Long = 1
|
||||
@JvmStatic
|
||||
private val serialVersionUID: Long = 1
|
||||
}
|
||||
|
||||
val configs = HashMap<String, Config>()
|
||||
|
|
|
@ -21,20 +21,23 @@ import android.os.Parcel
|
|||
import android.os.Parcelable
|
||||
import java.io.Serializable
|
||||
|
||||
data class Field(var hint: String,
|
||||
var digits: String,
|
||||
var alpha: Boolean,
|
||||
val alt: Boolean,
|
||||
val zeros: Boolean,
|
||||
var minSize: Int,
|
||||
var size: Int,
|
||||
var min: Int,
|
||||
var max: Int) : Parcelable, Serializable {
|
||||
|
||||
data class Field(
|
||||
var hint: String,
|
||||
var digits: String,
|
||||
var alpha: Boolean,
|
||||
val alt: Boolean,
|
||||
val zeros: Boolean,
|
||||
var minSize: Int,
|
||||
var size: Int,
|
||||
var min: Int,
|
||||
var max: Int
|
||||
) : Parcelable, Serializable {
|
||||
companion object {
|
||||
private @JvmStatic val serialVersionUID: Long = 1
|
||||
@JvmStatic
|
||||
private val serialVersionUID: Long = 1
|
||||
|
||||
@JvmField val CREATOR: Parcelable.Creator<Field> = object : Parcelable.Creator<Field> {
|
||||
@JvmField
|
||||
val CREATOR: Parcelable.Creator<Field> = object : Parcelable.Creator<Field> {
|
||||
override fun createFromParcel(source: Parcel): Field = Field(source)
|
||||
override fun newArray(size: Int): Array<Field?> = arrayOfNulls(size)
|
||||
}
|
||||
|
@ -43,15 +46,15 @@ data class Field(var hint: String,
|
|||
constructor() : this("", "", false, false, false, -1, -1, -1, -1)
|
||||
|
||||
constructor(source: Parcel) : this(
|
||||
source.readString(),
|
||||
source.readString(),
|
||||
1 == source.readInt(),
|
||||
1 == source.readInt(),
|
||||
1 == source.readInt(),
|
||||
source.readInt(),
|
||||
source.readInt(),
|
||||
source.readInt(),
|
||||
source.readInt())
|
||||
source.readString(),
|
||||
source.readString(),
|
||||
1 == source.readInt(),
|
||||
1 == source.readInt(),
|
||||
1 == source.readInt(),
|
||||
source.readInt(),
|
||||
source.readInt(),
|
||||
source.readInt(),
|
||||
source.readInt())
|
||||
|
||||
override fun describeContents() = 0
|
||||
|
||||
|
|
|
@ -21,16 +21,19 @@ import android.os.Parcel
|
|||
import android.os.Parcelable
|
||||
import java.io.Serializable
|
||||
|
||||
data class Option(var title: String,
|
||||
var fields: List<Field?>,
|
||||
var nodial: Boolean,
|
||||
var nosteps: Boolean,
|
||||
var dtmf: String) : Parcelable, Serializable, Comparable<Option> {
|
||||
|
||||
data class Option(
|
||||
var title: String,
|
||||
var fields: List<Field?>,
|
||||
var nodial: Boolean,
|
||||
var nosteps: Boolean,
|
||||
var dtmf: String
|
||||
) : Parcelable, Serializable, Comparable<Option> {
|
||||
companion object {
|
||||
private @JvmStatic val serialVersionUID: Long = 1
|
||||
@JvmStatic
|
||||
private val serialVersionUID: Long = 1
|
||||
|
||||
@JvmField val CREATOR: Parcelable.Creator<Option> = object : Parcelable.Creator<Option> {
|
||||
@JvmField
|
||||
val CREATOR: Parcelable.Creator<Option> = object : Parcelable.Creator<Option> {
|
||||
override fun createFromParcel(source: Parcel): Option = Option(source)
|
||||
override fun newArray(size: Int): Array<Option?> = arrayOfNulls(size)
|
||||
}
|
||||
|
@ -39,11 +42,11 @@ data class Option(var title: String,
|
|||
constructor() : this("", emptyList(), false, false, "")
|
||||
|
||||
constructor(source: Parcel) : this(
|
||||
source.readString(),
|
||||
source.createTypedArrayList(Field.CREATOR),
|
||||
1 == source.readInt(),
|
||||
1 == source.readInt(),
|
||||
source.readString())
|
||||
source.readString(),
|
||||
source.createTypedArrayList(Field.CREATOR),
|
||||
1 == source.readInt(),
|
||||
1 == source.readInt(),
|
||||
source.readString())
|
||||
|
||||
override fun compareTo(other: Option): Int = title.compareTo(other.title)
|
||||
|
||||
|
@ -56,5 +59,4 @@ data class Option(var title: String,
|
|||
dest?.writeInt((if (nosteps) 1 else 0))
|
||||
dest?.writeString(dtmf)
|
||||
}
|
||||
|
||||
}
|
|
@ -21,20 +21,23 @@ import android.os.Parcel
|
|||
import android.os.Parcelable
|
||||
import java.io.Serializable
|
||||
|
||||
data class Params(var name: String,
|
||||
var type: String,
|
||||
var phone: String,
|
||||
var master: String,
|
||||
var size: Int,
|
||||
var ack: String,
|
||||
var alt: String,
|
||||
var begin: String,
|
||||
var end: String) : Parcelable, Serializable {
|
||||
|
||||
data class Params(
|
||||
var name: String,
|
||||
var type: String,
|
||||
var phone: String,
|
||||
var master: String,
|
||||
var size: Int,
|
||||
var ack: String,
|
||||
var alt: String,
|
||||
var begin: String,
|
||||
var end: String
|
||||
) : Parcelable, Serializable {
|
||||
companion object {
|
||||
private @JvmStatic val serialVersionUID: Long = 1
|
||||
@JvmStatic
|
||||
private val serialVersionUID: Long = 1
|
||||
|
||||
@JvmField val CREATOR: Parcelable.Creator<Params> = object : Parcelable.Creator<Params> {
|
||||
@JvmField
|
||||
val CREATOR: Parcelable.Creator<Params> = object : Parcelable.Creator<Params> {
|
||||
override fun createFromParcel(source: Parcel): Params = Params(source)
|
||||
override fun newArray(size: Int): Array<Params?> = arrayOfNulls(size)
|
||||
}
|
||||
|
@ -43,15 +46,15 @@ data class Params(var name: String,
|
|||
constructor() : this("", "", "", "", -1, "", "", "", "")
|
||||
|
||||
constructor(source: Parcel) : this(
|
||||
source.readString(),
|
||||
source.readString(),
|
||||
source.readString(),
|
||||
source.readString(),
|
||||
source.readInt(),
|
||||
source.readString(),
|
||||
source.readString(),
|
||||
source.readString(),
|
||||
source.readString())
|
||||
source.readString(),
|
||||
source.readString(),
|
||||
source.readString(),
|
||||
source.readString(),
|
||||
source.readInt(),
|
||||
source.readString(),
|
||||
source.readString(),
|
||||
source.readString(),
|
||||
source.readString())
|
||||
|
||||
override fun describeContents() = 0
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ class CrashEmail(private val config: ACRAConfiguration) : ReportSender {
|
|||
override fun send(context: Context, errorContent: CrashReportData) {
|
||||
|
||||
val subject = context.getString(R.string.crash_report_subject,
|
||||
context.getString(R.string.app_name))
|
||||
context.getString(R.string.app_name))
|
||||
val body = buildBody(errorContent)
|
||||
|
||||
val emailIntent = Intent(android.content.Intent.ACTION_SENDTO)
|
||||
|
|
|
@ -24,5 +24,5 @@ import org.acra.sender.ReportSenderFactory
|
|||
|
||||
class CrashEmailFactory : ReportSenderFactory {
|
||||
override fun create(context: Context, config: ACRAConfiguration): ReportSender =
|
||||
CrashEmail(config)
|
||||
CrashEmail(config)
|
||||
}
|
|
@ -28,7 +28,7 @@ import org.acra.dialog.BaseCrashReportDialog
|
|||
import org.jetbrains.anko.find
|
||||
|
||||
class CrashReportActivity : BaseCrashReportDialog(), DialogInterface.OnDismissListener,
|
||||
DialogInterface.OnClickListener {
|
||||
DialogInterface.OnClickListener {
|
||||
private var comment: EditText? = null
|
||||
|
||||
companion object {
|
||||
|
@ -39,11 +39,11 @@ class CrashReportActivity : BaseCrashReportDialog(), DialogInterface.OnDismissLi
|
|||
super.init(savedInstanceState)
|
||||
|
||||
val dialog = AlertDialog.Builder(this)
|
||||
.setTitle(getString(R.string.crash_dialog_title, getString(R.string.app_name)))
|
||||
.setView(R.layout.crash_report_dialog)
|
||||
.setPositiveButton(R.string.ok, this)
|
||||
.setNegativeButton(R.string.cancel, this)
|
||||
.create()
|
||||
.setTitle(getString(R.string.crash_dialog_title, getString(R.string.app_name)))
|
||||
.setView(R.layout.crash_report_dialog)
|
||||
.setPositiveButton(R.string.ok, this)
|
||||
.setNegativeButton(R.string.cancel, this)
|
||||
.create()
|
||||
|
||||
dialog.setCanceledOnTouchOutside(false)
|
||||
dialog.setOnDismissListener(this)
|
||||
|
|
|
@ -20,7 +20,7 @@ package net.thauvin.erik.android.tesremoteprogrammer.util
|
|||
import android.widget.EditText
|
||||
import net.thauvin.erik.android.tesremoteprogrammer.MainActivity
|
||||
import net.thauvin.erik.android.tesremoteprogrammer.models.Option
|
||||
import java.util.*
|
||||
import java.util.ArrayList
|
||||
|
||||
class Dtmf {
|
||||
companion object {
|
||||
|
@ -89,7 +89,6 @@ class Dtmf {
|
|||
|
||||
fun isValidType(type: String): Boolean = type.equals(DKS, true) || type.equals(LINEAR, true)
|
||||
|
||||
|
||||
private fun linearAlphaToDigits(text: String): String {
|
||||
val result = StringBuffer()
|
||||
|
||||
|
@ -150,22 +149,24 @@ class Dtmf {
|
|||
return result.toString()
|
||||
}
|
||||
|
||||
fun build(type: String,
|
||||
master: String,
|
||||
ack: String,
|
||||
option: Option,
|
||||
fields: ArrayList<EditText>): String {
|
||||
fun build(
|
||||
type: String,
|
||||
master: String,
|
||||
ack: String,
|
||||
option: Option,
|
||||
fields: ArrayList<EditText>
|
||||
): String {
|
||||
val replace = arrayListOf(Pair(DTMF_MASTER, master))
|
||||
|
||||
fields.forEachIndexed { i, field ->
|
||||
replace.add(Pair(DTMF_FIELD.format(i + 1),
|
||||
if (option.fields[i]!!.alpha && type.isDKS()) {
|
||||
dksAlphaToDigits(field.text.toString(), ack)
|
||||
} else if (option.fields[i]!!.alpha && type.isLinear()) {
|
||||
linearAlphaToDigits(field.text.toString())
|
||||
} else {
|
||||
field.text.toString()
|
||||
}))
|
||||
if (option.fields[i]!!.alpha && type.isDKS()) {
|
||||
dksAlphaToDigits(field.text.toString(), ack)
|
||||
} else if (option.fields[i]!!.alpha && type.isLinear()) {
|
||||
linearAlphaToDigits(field.text.toString())
|
||||
} else {
|
||||
field.text.toString()
|
||||
}))
|
||||
}
|
||||
|
||||
return option.dtmf.replaceAll(replace.toTypedArray())
|
||||
|
|
|
@ -23,26 +23,30 @@ import android.support.v4.view.ViewCompat
|
|||
import android.view.View
|
||||
|
||||
class ScrollAwareFABBehavior : FloatingActionButton.Behavior() {
|
||||
override fun onStartNestedScroll(coordinatorLayout: CoordinatorLayout,
|
||||
child: FloatingActionButton,
|
||||
directTargetChild: View,
|
||||
target: View,
|
||||
nestedScrollAxes: Int,
|
||||
type: Int): Boolean =
|
||||
nestedScrollAxes == ViewCompat.SCROLL_AXIS_VERTICAL ||
|
||||
super.onStartNestedScroll(coordinatorLayout, child, directTargetChild, target,
|
||||
nestedScrollAxes, type)
|
||||
override fun onStartNestedScroll(
|
||||
coordinatorLayout: CoordinatorLayout,
|
||||
child: FloatingActionButton,
|
||||
directTargetChild: View,
|
||||
target: View,
|
||||
nestedScrollAxes: Int,
|
||||
type: Int
|
||||
): Boolean =
|
||||
nestedScrollAxes == ViewCompat.SCROLL_AXIS_VERTICAL ||
|
||||
super.onStartNestedScroll(coordinatorLayout, child, directTargetChild, target,
|
||||
nestedScrollAxes, type)
|
||||
|
||||
override fun onNestedScroll(coordinatorLayout: CoordinatorLayout,
|
||||
child: FloatingActionButton,
|
||||
target: View,
|
||||
dxConsumed: Int,
|
||||
dyConsumed: Int,
|
||||
dxUnconsumed: Int,
|
||||
dyUnconsumed: Int,
|
||||
type: Int) {
|
||||
override fun onNestedScroll(
|
||||
coordinatorLayout: CoordinatorLayout,
|
||||
child: FloatingActionButton,
|
||||
target: View,
|
||||
dxConsumed: Int,
|
||||
dyConsumed: Int,
|
||||
dxUnconsumed: Int,
|
||||
dyUnconsumed: Int,
|
||||
type: Int
|
||||
) {
|
||||
super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed,
|
||||
dxUnconsumed, dyUnconsumed, type)
|
||||
dxUnconsumed, dyUnconsumed, type)
|
||||
if (dyConsumed > 0 && child.visibility == View.VISIBLE) {
|
||||
// see: https://stackoverflow.com/a/42082313/5640587
|
||||
child.hide(object : FloatingActionButton.OnVisibilityChangedListener() {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue