From 72e75f3eaa0beccbbcf13d34277ffb8410a5a43d Mon Sep 17 00:00:00 2001 From: "Erik C. Thauvin" Date: Wed, 31 Aug 2016 09:16:29 -0700 Subject: [PATCH] Added digits field property. --- README.md | 19 +-- .../tesremoteprogrammer/MainActivity.kt | 9 ++ .../ProgrammingActivity.kt | 3 +- .../filters/AlphaFilter.kt | 2 +- .../filters/NumberFilter.kt | 13 +- .../tesremoteprogrammer/models/Field.kt | 5 +- .../android/tesremoteprogrammer/util/Dtmf.kt | 117 +++++++++--------- .../tesremoteprogrammer/util/Strings.kt | 14 +++ app/src/main/res/raw/dks_1802.json | 27 +++- app/src/main/res/raw/dks_1802_epd.json | 27 +++- app/src/main/res/raw/dks_1803_1808_1810.json | 27 +++- app/src/main/res/raw/dks_1812.json | 12 +- app/src/main/res/raw/dks_1819.json | 3 +- 13 files changed, 192 insertions(+), 86 deletions(-) diff --git a/README.md b/README.md index f1a1c58..7696928 100644 --- a/README.md +++ b/README.md @@ -54,14 +54,14 @@ Parameters define the configuration's global settings. } ``` -| Parameter | Description | Required | -|:-----------|:-------------------------------------------------------------------------------------------------|:---------| -|`name` | The name of the configuration. | Yes | -|`ack` | The key used to acknowledge or terminate programming steps. Most systems use the `*` or `#` key. | Yes | -|`alt` | They key used to in place of numbers when applicable. DKS systems use the `#` key | No | -|`begin` | The begin programming manual sequence. For example Linear uses `0` and `2` pressed together. | No | -|`end` | The end programming manual sequence. For example DSK uses `0` and `#` pressed together. | No | -|`size` | The size (number of digits) of the master code. Most systems use 4 or 6. | Yes | +| Property | Description | Required | +|:---------|:-------------------------------------------------------------------------------------------------|:---------| +|`name` | The name of the configuration. | Yes | +|`ack` | The key used to acknowledge or terminate programming steps. Most systems use the `*` or `#` key. | Yes | +|`alt` | They key used to in place of numbers when applicable. DKS systems use the `#` key | No | +|`begin` | The begin programming manual sequence. For example Linear uses `0` and `2` pressed together. | No | +|`end` | The end programming manual sequence. For example DSK uses `0` and `#` pressed together. | No | +|`size` | The size (number of digits) of the master code. Most systems use 4 or 6. | Yes | ### Options @@ -134,7 +134,8 @@ Fields represent the data entry text fields on option screens. |`min` | Set the minimum value of a numeric field. | No | |`max` | Set the maximum value of a numeric field. | No | |`alpha` | Set to `dks` or `linear` for alphanumeric fields. | No | -|`alt` | Set to `true` if the field accepts the `alt` [parameter](#parameters) value in place of a digit. | No | +'`digits` | Set digits that are allowed. For example DKS uses `1234567` for days of the week: Sun=1... Sat=7. | No | +|`alt` | Set to `true` if the field accepts the `alt` [parameter](#parameters) value in place of a digit. | No | |`zeros` | Set to `true` by default. Allows numeric values with leading zeros (i.e. `001`), based on the `size`. | No | diff --git a/app/src/main/java/net/thauvin/erik/android/tesremoteprogrammer/MainActivity.kt b/app/src/main/java/net/thauvin/erik/android/tesremoteprogrammer/MainActivity.kt index 18e1b52..4f48ab7 100644 --- a/app/src/main/java/net/thauvin/erik/android/tesremoteprogrammer/MainActivity.kt +++ b/app/src/main/java/net/thauvin/erik/android/tesremoteprogrammer/MainActivity.kt @@ -44,6 +44,7 @@ import com.google.gson.JsonSyntaxException import net.thauvin.erik.android.tesremoteprogrammer.models.Config import net.thauvin.erik.android.tesremoteprogrammer.models.Configurations import net.thauvin.erik.android.tesremoteprogrammer.util.Dtmf +import net.thauvin.erik.android.tesremoteprogrammer.util.isDigits import org.jetbrains.anko.* import org.jetbrains.anko.design.textInputLayout import permissions.dispatcher.NeedsPermission @@ -382,6 +383,14 @@ class MainActivity : AppCompatActivity(), AnkoLogger { errors.append(getString(R.string.validate_invalid_attr, i + 1, j + 1, "minSize/size")) } + if (field.digits.isNotBlank() && !field.digits.isDigits()) { + errors.append(getString(R.string.validate_invalid_attr, i + 1, j + 1, "digits")) + } + + if (!Dtmf.isValidAlpha(field.alpha)) { + errors.append(getString(R.string.validate_invalid_attr, i + 1, j + 1, "alpha")) + } + if (field.alpha.isBlank()) { if (field.min >= 0 || field.max >= 0) { if (field.max < 1) { diff --git a/app/src/main/java/net/thauvin/erik/android/tesremoteprogrammer/ProgrammingActivity.kt b/app/src/main/java/net/thauvin/erik/android/tesremoteprogrammer/ProgrammingActivity.kt index 91734cf..2291730 100644 --- a/app/src/main/java/net/thauvin/erik/android/tesremoteprogrammer/ProgrammingActivity.kt +++ b/app/src/main/java/net/thauvin/erik/android/tesremoteprogrammer/ProgrammingActivity.kt @@ -108,8 +108,7 @@ class ProgrammingActivity : AppCompatActivity(), AnkoLogger { } } else { inputType = InputType.TYPE_CLASS_PHONE - inputFilters.add(NumberFilter("0123456789" + - if (field.alt) "${params.alt}" else "")) + inputFilters.add(NumberFilter(field.digits, if (field.alt) params.alt else "")) if (field.max != -1 && field.min != -1) { inputFilters.add( MinMaxFilter(field.min, field.max, field.size, field.zeros)) diff --git a/app/src/main/java/net/thauvin/erik/android/tesremoteprogrammer/filters/AlphaFilter.kt b/app/src/main/java/net/thauvin/erik/android/tesremoteprogrammer/filters/AlphaFilter.kt index 4f66cce..ac330c7 100644 --- a/app/src/main/java/net/thauvin/erik/android/tesremoteprogrammer/filters/AlphaFilter.kt +++ b/app/src/main/java/net/thauvin/erik/android/tesremoteprogrammer/filters/AlphaFilter.kt @@ -48,7 +48,7 @@ class AlphaFilter : InputFilter { for (i in start..end - 1) { val c = source[i] if (c.isLetterOrDigit() || extras.contains(c)) { - sb.append(c.toUpperCase()) + sb.append(c) } } return sb.toString() diff --git a/app/src/main/java/net/thauvin/erik/android/tesremoteprogrammer/filters/NumberFilter.kt b/app/src/main/java/net/thauvin/erik/android/tesremoteprogrammer/filters/NumberFilter.kt index f7b45a6..0beb552 100644 --- a/app/src/main/java/net/thauvin/erik/android/tesremoteprogrammer/filters/NumberFilter.kt +++ b/app/src/main/java/net/thauvin/erik/android/tesremoteprogrammer/filters/NumberFilter.kt @@ -20,12 +20,19 @@ package net.thauvin.erik.android.tesremoteprogrammer.filters import android.text.InputFilter import android.text.SpannableStringBuilder import android.text.Spanned +import net.thauvin.erik.android.tesremoteprogrammer.util.isDigits +import org.jetbrains.anko.AnkoLogger -class NumberFilter : InputFilter { +class NumberFilter : InputFilter, AnkoLogger { private val allowed: String + private val digits = "0123456789" - constructor(allowed: String) { - this.allowed = allowed + constructor(allowed: String, alt: String) { + this.allowed = if (allowed.isDigits()) { + "$allowed$alt" + } else { + "$digits$alt" + } } override fun filter(source: CharSequence, diff --git a/app/src/main/java/net/thauvin/erik/android/tesremoteprogrammer/models/Field.kt b/app/src/main/java/net/thauvin/erik/android/tesremoteprogrammer/models/Field.kt index 640bbcd..06a23b1 100644 --- a/app/src/main/java/net/thauvin/erik/android/tesremoteprogrammer/models/Field.kt +++ b/app/src/main/java/net/thauvin/erik/android/tesremoteprogrammer/models/Field.kt @@ -23,6 +23,7 @@ import java.io.Serializable data class Field(var hint: String, var alpha: String, + var digits: String, val alt: Boolean, var zeros: Boolean, var minSize: Int, @@ -39,9 +40,10 @@ data class Field(var hint: String, } } - constructor() : this("", "", false, true, -1, -1, -1, -1) + constructor() : this("", "", "", false, true, -1, -1, -1, -1) constructor(source: Parcel) : this( + source.readString(), source.readString(), source.readString(), 1.equals(source.readInt()), @@ -56,6 +58,7 @@ data class Field(var hint: String, override fun writeToParcel(dest: Parcel?, flags: Int) { dest?.writeString(hint) dest?.writeString(alpha) + dest?.writeString(digits) dest?.writeInt((if (alt) 1 else 0)) dest?.writeInt((if (zeros) 1 else 0)) dest?.writeInt(minSize) diff --git a/app/src/main/java/net/thauvin/erik/android/tesremoteprogrammer/util/Dtmf.kt b/app/src/main/java/net/thauvin/erik/android/tesremoteprogrammer/util/Dtmf.kt index 34a5296..9d4cf97 100644 --- a/app/src/main/java/net/thauvin/erik/android/tesremoteprogrammer/util/Dtmf.kt +++ b/app/src/main/java/net/thauvin/erik/android/tesremoteprogrammer/util/Dtmf.kt @@ -31,6 +31,67 @@ class Dtmf { val DKS_EXTRAS = " " val LINEAR_EXTRAS = ", -." + private fun dksAlphaToDigits(text: String, ack: String): String { + val result = StringBuffer() + + text.toUpperCase().forEach { c -> + when (c) { + 'A' -> result.append("2$ack${MainActivity.PAUSE}") + 'B' -> result.append("22$ack${MainActivity.PAUSE}") + 'C' -> result.append("222$ack${MainActivity.PAUSE}") + + 'D' -> result.append("3$ack${MainActivity.PAUSE}") + 'E' -> result.append("33$ack${MainActivity.PAUSE}") + 'F' -> result.append("333$ack${MainActivity.PAUSE}") + + 'G' -> result.append("4$ack${MainActivity.PAUSE}") + 'H' -> result.append("44$ack${MainActivity.PAUSE}") + 'I' -> result.append("444$ack${MainActivity.PAUSE}") + + 'J' -> result.append("5$ack${MainActivity.PAUSE}") + 'K' -> result.append("55$ack${MainActivity.PAUSE}") + 'L' -> result.append("555$ack${MainActivity.PAUSE}") + + 'M' -> result.append("6$ack${MainActivity.PAUSE}") + 'N' -> result.append("66$ack${MainActivity.PAUSE}") + 'O' -> result.append("666$ack${MainActivity.PAUSE}") + + 'P' -> result.append("7$ack${MainActivity.PAUSE}") + 'Q' -> result.append("77$ack${MainActivity.PAUSE}") + 'R' -> result.append("777$ack${MainActivity.PAUSE}") + 'S' -> result.append("7777$ack${MainActivity.PAUSE}") + + 'T' -> result.append("8$ack${MainActivity.PAUSE}") + 'U' -> result.append("88$ack${MainActivity.PAUSE}") + 'V' -> result.append("888$ack${MainActivity.PAUSE}") + + 'W' -> result.append("9$ack${MainActivity.PAUSE}") + 'X' -> result.append("99$ack${MainActivity.PAUSE}") + 'Y' -> result.append("999$ack${MainActivity.PAUSE}") + 'Z' -> result.append("9999$ack${MainActivity.PAUSE}") + + '0' -> result.append("0$ack${MainActivity.PAUSE}") + '1' -> result.append("11$ack${MainActivity.PAUSE}") + '2' -> result.append("2222$ack${MainActivity.PAUSE}") + '3' -> result.append("3333$ack${MainActivity.PAUSE}") + '4' -> result.append("4444$ack${MainActivity.PAUSE}") + '5' -> result.append("5555$ack${MainActivity.PAUSE}") + '6' -> result.append("6666$ack${MainActivity.PAUSE}") + '7' -> result.append("77777$ack${MainActivity.PAUSE}") + '8' -> result.append("8888$ack${MainActivity.PAUSE}") + '9' -> result.append("99999$ack${MainActivity.PAUSE}") + + ' ' -> result.append("1$ack${MainActivity.PAUSE}") + } + } + return result.toString() + } + + fun isValidAlpha(alpha: String) : Boolean { + return alpha.isBlank() || alpha.equals(DKS, true) || alpha.equals(LINEAR, true) + } + + private fun linearAlphaToDigits(text: String): String { val result = StringBuffer() @@ -91,62 +152,6 @@ class Dtmf { return result.toString() } - private fun dksAlphaToDigits(text: String, ack: String): String { - val result = StringBuffer() - - text.toUpperCase().forEach { c -> - when (c) { - 'A' -> result.append("2$ack${MainActivity.PAUSE}") - 'B' -> result.append("22$ack${MainActivity.PAUSE}") - 'C' -> result.append("222$ack${MainActivity.PAUSE}") - - 'D' -> result.append("3$ack${MainActivity.PAUSE}") - 'E' -> result.append("33$ack${MainActivity.PAUSE}") - 'F' -> result.append("333$ack${MainActivity.PAUSE}") - - 'G' -> result.append("4$ack${MainActivity.PAUSE}") - 'H' -> result.append("44$ack${MainActivity.PAUSE}") - 'I' -> result.append("444$ack${MainActivity.PAUSE}") - - 'J' -> result.append("5$ack${MainActivity.PAUSE}") - 'K' -> result.append("55$ack${MainActivity.PAUSE}") - 'L' -> result.append("555$ack${MainActivity.PAUSE}") - - 'M' -> result.append("6$ack${MainActivity.PAUSE}") - 'N' -> result.append("66$ack${MainActivity.PAUSE}") - 'O' -> result.append("666$ack${MainActivity.PAUSE}") - - 'P' -> result.append("7$ack${MainActivity.PAUSE}") - 'Q' -> result.append("77$ack${MainActivity.PAUSE}") - 'R' -> result.append("777$ack${MainActivity.PAUSE}") - 'S' -> result.append("7777$ack${MainActivity.PAUSE}") - - 'T' -> result.append("8$ack${MainActivity.PAUSE}") - 'U' -> result.append("88$ack${MainActivity.PAUSE}") - 'V' -> result.append("888$ack${MainActivity.PAUSE}") - - 'W' -> result.append("9$ack${MainActivity.PAUSE}") - 'X' -> result.append("99$ack${MainActivity.PAUSE}") - 'Y' -> result.append("999$ack${MainActivity.PAUSE}") - 'Z' -> result.append("9999$ack${MainActivity.PAUSE}") - - '0' -> result.append("0$ack${MainActivity.PAUSE}") - '1' -> result.append("11$ack${MainActivity.PAUSE}") - '2' -> result.append("2222$ack${MainActivity.PAUSE}") - '3' -> result.append("3333$ack${MainActivity.PAUSE}") - '4' -> result.append("4444$ack${MainActivity.PAUSE}") - '5' -> result.append("5555$ack${MainActivity.PAUSE}") - '6' -> result.append("6666$ack${MainActivity.PAUSE}") - '7' -> result.append("77777$ack${MainActivity.PAUSE}") - '8' -> result.append("8888$ack${MainActivity.PAUSE}") - '9' -> result.append("99999$ack${MainActivity.PAUSE}") - - ' ' -> result.append("1$ack${MainActivity.PAUSE}") - } - } - return result.toString() - } - fun build(master: String, ack: String, option: Option, diff --git a/app/src/main/java/net/thauvin/erik/android/tesremoteprogrammer/util/Strings.kt b/app/src/main/java/net/thauvin/erik/android/tesremoteprogrammer/util/Strings.kt index 8c3b937..cd0d38a 100644 --- a/app/src/main/java/net/thauvin/erik/android/tesremoteprogrammer/util/Strings.kt +++ b/app/src/main/java/net/thauvin/erik/android/tesremoteprogrammer/util/Strings.kt @@ -17,6 +17,20 @@ */ package net.thauvin.erik.android.tesremoteprogrammer.util +fun String.isDigits() : Boolean { + if (isBlank()) { + return false + } + + forEach { + if (!it.isDigit()) { + return false + } + } + + return true +} + fun String.replaceAll(replace: Array>): String { val result = StringBuilder(this) var offset: Int diff --git a/app/src/main/res/raw/dks_1802.json b/app/src/main/res/raw/dks_1802.json index 02b46f9..67b74c8 100644 --- a/app/src/main/res/raw/dks_1802.json +++ b/app/src/main/res/raw/dks_1802.json @@ -330,11 +330,30 @@ { "hint": "Days of Week (Sun=1, Sat=7 or #)", "size": 7, - "alt": true + "alt": true, + "digits": "1234567" } ], "dtmf": "*35[MASTER],[FIELD:1]*,[FIELD:2]*,[FIELD:3][FIELD:4]*,[FIELD:5]*,[FIELD:6][FIELD:7]*,[FIELD:8]*,[FIELD:9]*" }, + { + "title": "Enable/Disable Automatic Relay Time Zone", + "fields": [ + { + "hint": "Time Zone (1..4)", + "size": 1, + "min": 1, + "max": 4 + }, + { + "hint": "OFF=0 ON=1", + "size": 1, + "min": 0, + "max": 1 + } + ], + "dtmf": "*35[MASTER],[FIELD:1]*,[FIELD:2]*" + }, { "title": "Set 4-Digit Entry Code Time Zone", "fields": [ @@ -383,7 +402,8 @@ { "hint": "Days of Week (Sun=1..Sat=7 or #)", "size": 7, - "alt": true + "alt": true, + "digits": "1234567" }, { "hint": "Lower 4-Digit Boundary", @@ -456,7 +476,8 @@ { "hint": "Days of Week (Sun=1..Sat=7 or #)", "size": 7, - "alt": true + "alt": true, + "digits": "1234567" }, { "hint": "Lower 4-Digit Boundary", diff --git a/app/src/main/res/raw/dks_1802_epd.json b/app/src/main/res/raw/dks_1802_epd.json index 140cbda..2b7b5f1 100644 --- a/app/src/main/res/raw/dks_1802_epd.json +++ b/app/src/main/res/raw/dks_1802_epd.json @@ -330,11 +330,30 @@ { "hint": "Days of Week (Sun=1, Sat=7 or #)", "size": 7, - "alt": true + "alt": true, + "digits": "1234567" } ], "dtmf": "*35[MASTER],[FIELD:1]*,[FIELD:2]*,[FIELD:3][FIELD:4]*,[FIELD:5]*,[FIELD:6][FIELD:7]*,[FIELD:8]*,[FIELD:9]*" }, + { + "title": "Enable/Disable Automatic Relay Time Zone", + "fields": [ + { + "hint": "Time Zone (1..4)", + "size": 1, + "min": 1, + "max": 4 + }, + { + "hint": "OFF=0 ON=1", + "size": 1, + "min": 0, + "max": 1 + } + ], + "dtmf": "*35[MASTER],[FIELD:1]*,[FIELD:2]*" + }, { "title": "Set 4-Digit Entry Code Time Zone", "fields": [ @@ -383,7 +402,8 @@ { "hint": "Days of Week (Sun=1..Sat=7 or #)", "size": 7, - "alt": true + "alt": true, + "digits": "1234567" }, { "hint": "Lower 4-Digit Boundary", @@ -456,7 +476,8 @@ { "hint": "Days of Week (Sun=1..Sat=7 or #)", "size": 7, - "alt": true + "alt": true, + "digits": "1234567" }, { "hint": "Lower 4-Digit Boundary", diff --git a/app/src/main/res/raw/dks_1803_1808_1810.json b/app/src/main/res/raw/dks_1803_1808_1810.json index b50324c..9131fbc 100644 --- a/app/src/main/res/raw/dks_1803_1808_1810.json +++ b/app/src/main/res/raw/dks_1803_1808_1810.json @@ -202,11 +202,30 @@ { "hint": "Days of Week (Sun=1, Sat=7 or #)", "size": 7, - "alt": true + "alt": true, + "digits": "1234567" } ], "dtmf": "*35[MASTER],[FIELD:1][FIELD:2]*,[FIELD:3][FIELD:4]*,[FIELD:5]*,[FIELD:6]*,[FIELD:7]*" }, + { + "title": "Enable/Disable Automatic Relay Time Zone", + "fields": [ + { + "hint": "Time Zone (1..4)", + "size": 1, + "min": 1, + "max": 4 + }, + { + "hint": "OFF=0 ON=1", + "size": 1, + "min": 0, + "max": 1 + } + ], + "dtmf": "*35[MASTER],[FIELD:1]*,[FIELD:2]*" + }, { "title": "Set 4-Digit Entry Code Time Zone", "fields": [ @@ -231,7 +250,8 @@ { "hint": "Days of Week (Sun=1..Sat=7 or #)", "size": 7, - "alt": true + "alt": true, + "digits": "1234567" }, { "hint": "Lower 4-Digit Boundary", @@ -268,7 +288,8 @@ { "hint": "Days of Week (Sun=1, Sat=7 or #)", "size": 7, - "alt": true + "alt": true, + "digits": "1234567" }, { "hint": "Lower 5-Digit Boundary", diff --git a/app/src/main/res/raw/dks_1812.json b/app/src/main/res/raw/dks_1812.json index 34c9d03..883ee0a 100644 --- a/app/src/main/res/raw/dks_1812.json +++ b/app/src/main/res/raw/dks_1812.json @@ -113,7 +113,8 @@ { "hint": "Active Days of Week (Sun=1..Sat=7, or #)", "size": 7, - "alt": true + "alt": true, + "digits": "1234567" } ], "dtmf": "*34[MASTER],[FIELD:1]*,[FIELD:2][FIELD:3]*,[FIELD:4]*,[FIELD:5]*" @@ -148,7 +149,8 @@ { "hint": "Active Days of Week (Sun=1..Sat=7, or #)", "size": 7, - "alt": true + "alt": true, + "digits": "1234567" } ], "dtmf": "*35[MASTER],[FIELD:1]*,[FIELD:2][FIELD:3]*,[FIELD:4]*,[FIELD:5]*" @@ -201,7 +203,8 @@ { "hint": "Active Days of Week (Sun=1..Sat=7, or #)", "size": 7, - "alt": true + "alt": true, + "digits": "1234567" } ], "dtmf": "*36[MASTER],[FIELD:1]*,[FIELD:2][FIELD:3][FIELD:4]*,[FIELD:5][FIELD:6][FIELD:7]*,[FIELD:8]" @@ -254,7 +257,8 @@ { "hint": "Active Days of Week (Sun=1..Sat=7, or #)", "size": 7, - "alt": true + "alt": true, + "digits": "1234567" } ], "dtmf": "*37[MASTER],[FIELD:1]*,[FIELD:2][FIELD:3][FIELD:4]*,[FIELD:5][FIELD:6][FIELD:7]*,[FIELD:8]" diff --git a/app/src/main/res/raw/dks_1819.json b/app/src/main/res/raw/dks_1819.json index bc7c4ad..28278d5 100644 --- a/app/src/main/res/raw/dks_1819.json +++ b/app/src/main/res/raw/dks_1819.json @@ -160,7 +160,8 @@ { "hint": "Days of Week (Sun=1, Sat=7 or #)", "size": 7, - "alt": true + "alt": true, + "digits": "1234567" } ], "dtmf": "*35[MASTER],[FIELD:1]*,[FIELD:2]*,[FIELD:3][FIELD:4]*,[FIELD:5][FIELD:6]*,[FIELD:7]*,[FIELD:8]*"