mirror of
https://github.com/SimpleMobileTools/Simple-Calculator.git
synced 2025-02-26 08:17:44 +01:00
Merge pull request #257 from Naveen3Singh/comma_as_decimal
Allow toggling comma/dot as decimal/thousands
This commit is contained in:
commit
47d6110a0f
@ -13,6 +13,7 @@ import com.simplemobiletools.calculator.databases.CalculatorDatabase
|
|||||||
import com.simplemobiletools.calculator.dialogs.HistoryDialog
|
import com.simplemobiletools.calculator.dialogs.HistoryDialog
|
||||||
import com.simplemobiletools.calculator.extensions.config
|
import com.simplemobiletools.calculator.extensions.config
|
||||||
import com.simplemobiletools.calculator.extensions.updateViewColors
|
import com.simplemobiletools.calculator.extensions.updateViewColors
|
||||||
|
import com.simplemobiletools.calculator.extensions.updateWidgets
|
||||||
import com.simplemobiletools.calculator.helpers.*
|
import com.simplemobiletools.calculator.helpers.*
|
||||||
import com.simplemobiletools.commons.extensions.*
|
import com.simplemobiletools.commons.extensions.*
|
||||||
import com.simplemobiletools.commons.helpers.LICENSE_AUTOFITTEXTVIEW
|
import com.simplemobiletools.commons.helpers.LICENSE_AUTOFITTEXTVIEW
|
||||||
@ -24,8 +25,11 @@ import me.grantland.widget.AutofitHelper
|
|||||||
class MainActivity : SimpleActivity(), Calculator {
|
class MainActivity : SimpleActivity(), Calculator {
|
||||||
private var storedTextColor = 0
|
private var storedTextColor = 0
|
||||||
private var vibrateOnButtonPress = true
|
private var vibrateOnButtonPress = true
|
||||||
|
private var storedUseCommaAsDecimalMark = false
|
||||||
|
private var decimalSeparator = DOT
|
||||||
|
private var groupingSeparator = COMMA
|
||||||
|
|
||||||
lateinit var calc: CalculatorImpl
|
private lateinit var calc: CalculatorImpl
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
@ -34,26 +38,28 @@ class MainActivity : SimpleActivity(), Calculator {
|
|||||||
|
|
||||||
calc = CalculatorImpl(this, applicationContext)
|
calc = CalculatorImpl(this, applicationContext)
|
||||||
|
|
||||||
btn_plus.setOnClickListener { calc.handleOperation(PLUS); checkHaptic(it) }
|
btn_plus.setOnClickOperation(PLUS)
|
||||||
btn_minus.setOnClickListener { calc.handleOperation(MINUS); checkHaptic(it) }
|
btn_minus.setOnClickOperation(MINUS)
|
||||||
btn_multiply.setOnClickListener { calc.handleOperation(MULTIPLY); checkHaptic(it) }
|
btn_multiply.setOnClickOperation(MULTIPLY)
|
||||||
btn_divide.setOnClickListener { calc.handleOperation(DIVIDE); checkHaptic(it) }
|
btn_divide.setOnClickOperation(DIVIDE)
|
||||||
btn_percent.setOnClickListener { calc.handleOperation(PERCENT); checkHaptic(it) }
|
btn_percent.setOnClickOperation(PERCENT)
|
||||||
btn_power.setOnClickListener { calc.handleOperation(POWER); checkHaptic(it) }
|
btn_power.setOnClickOperation(POWER)
|
||||||
btn_root.setOnClickListener { calc.handleOperation(ROOT); checkHaptic(it) }
|
btn_root.setOnClickOperation(ROOT)
|
||||||
|
btn_minus.setOnLongClickListener { calc.turnToNegative() }
|
||||||
|
|
||||||
btn_minus.setOnLongClickListener {
|
btn_clear.setVibratingOnClickListener { calc.handleClear() }
|
||||||
calc.turnToNegative()
|
btn_clear.setOnLongClickListener {
|
||||||
|
calc.handleReset()
|
||||||
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
btn_clear.setOnClickListener { calc.handleClear(); checkHaptic(it) }
|
|
||||||
btn_clear.setOnLongClickListener { calc.handleReset(); true }
|
|
||||||
|
|
||||||
getButtonIds().forEach {
|
getButtonIds().forEach {
|
||||||
it.setOnClickListener { calc.numpadClicked(it.id); checkHaptic(it) }
|
it.setVibratingOnClickListener { view ->
|
||||||
|
calc.numpadClicked(view.id)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
btn_equals.setOnClickListener { calc.handleEquals(); checkHaptic(it) }
|
btn_equals.setVibratingOnClickListener { calc.handleEquals() }
|
||||||
formula.setOnLongClickListener { copyToClipboard(false) }
|
formula.setOnLongClickListener { copyToClipboard(false) }
|
||||||
result.setOnLongClickListener { copyToClipboard(true) }
|
result.setOnLongClickListener { copyToClipboard(true) }
|
||||||
|
|
||||||
@ -61,6 +67,7 @@ class MainActivity : SimpleActivity(), Calculator {
|
|||||||
AutofitHelper.create(formula)
|
AutofitHelper.create(formula)
|
||||||
storeStateVariables()
|
storeStateVariables()
|
||||||
updateViewColors(calculator_holder, getProperTextColor())
|
updateViewColors(calculator_holder, getProperTextColor())
|
||||||
|
setupDecimalSeparator()
|
||||||
checkWhatsNewDialog()
|
checkWhatsNewDialog()
|
||||||
checkAppOnSDCard()
|
checkAppOnSDCard()
|
||||||
}
|
}
|
||||||
@ -75,6 +82,11 @@ class MainActivity : SimpleActivity(), Calculator {
|
|||||||
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
|
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (storedUseCommaAsDecimalMark != config.useCommaAsDecimalMark) {
|
||||||
|
setupDecimalSeparator()
|
||||||
|
updateWidgets()
|
||||||
|
}
|
||||||
|
|
||||||
vibrateOnButtonPress = config.vibrateOnButtonPress
|
vibrateOnButtonPress = config.vibrateOnButtonPress
|
||||||
|
|
||||||
val properPrimaryColor = getProperPrimaryColor()
|
val properPrimaryColor = getProperPrimaryColor()
|
||||||
@ -117,6 +129,7 @@ class MainActivity : SimpleActivity(), Calculator {
|
|||||||
private fun storeStateVariables() {
|
private fun storeStateVariables() {
|
||||||
config.apply {
|
config.apply {
|
||||||
storedTextColor = textColor
|
storedTextColor = textColor
|
||||||
|
storedUseCommaAsDecimalMark = useCommaAsDecimalMark
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,4 +199,30 @@ class MainActivity : SimpleActivity(), Calculator {
|
|||||||
override fun showNewFormula(value: String, context: Context) {
|
override fun showNewFormula(value: String, context: Context) {
|
||||||
formula.text = value
|
formula.text = value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun setupDecimalSeparator() {
|
||||||
|
storedUseCommaAsDecimalMark = config.useCommaAsDecimalMark
|
||||||
|
if (storedUseCommaAsDecimalMark) {
|
||||||
|
decimalSeparator = COMMA
|
||||||
|
groupingSeparator = DOT
|
||||||
|
} else {
|
||||||
|
decimalSeparator = DOT
|
||||||
|
groupingSeparator = COMMA
|
||||||
|
}
|
||||||
|
calc.updateSeparators(decimalSeparator, groupingSeparator)
|
||||||
|
btn_decimal.text = decimalSeparator
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun View.setVibratingOnClickListener(callback: (view: View) -> Unit) {
|
||||||
|
setOnClickListener {
|
||||||
|
callback(it)
|
||||||
|
checkHaptic(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun View.setOnClickOperation(operation: String) {
|
||||||
|
setVibratingOnClickListener {
|
||||||
|
calc.handleOperation(operation)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,13 +4,17 @@ import android.content.Intent
|
|||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import com.simplemobiletools.calculator.R
|
import com.simplemobiletools.calculator.R
|
||||||
|
import com.simplemobiletools.calculator.extensions.calculatorDB
|
||||||
import com.simplemobiletools.calculator.extensions.config
|
import com.simplemobiletools.calculator.extensions.config
|
||||||
|
import com.simplemobiletools.calculator.extensions.updateWidgets
|
||||||
import com.simplemobiletools.commons.extensions.*
|
import com.simplemobiletools.commons.extensions.*
|
||||||
import com.simplemobiletools.commons.helpers.IS_CUSTOMIZING_COLORS
|
import com.simplemobiletools.commons.helpers.IS_CUSTOMIZING_COLORS
|
||||||
|
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
|
||||||
import kotlinx.android.synthetic.main.activity_settings.*
|
import kotlinx.android.synthetic.main.activity_settings.*
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.system.exitProcess
|
import kotlin.system.exitProcess
|
||||||
|
|
||||||
|
|
||||||
class SettingsActivity : SimpleActivity() {
|
class SettingsActivity : SimpleActivity() {
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
@ -26,6 +30,7 @@ class SettingsActivity : SimpleActivity() {
|
|||||||
setupUseEnglish()
|
setupUseEnglish()
|
||||||
setupVibrate()
|
setupVibrate()
|
||||||
setupPreventPhoneFromSleeping()
|
setupPreventPhoneFromSleeping()
|
||||||
|
setupUseCommaAsDecimalMark()
|
||||||
setupCustomizeWidgetColors()
|
setupCustomizeWidgetColors()
|
||||||
updateTextColors(settings_scrollview)
|
updateTextColors(settings_scrollview)
|
||||||
|
|
||||||
@ -94,6 +99,18 @@ class SettingsActivity : SimpleActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun setupUseCommaAsDecimalMark() {
|
||||||
|
settings_use_comma_as_decimal_mark.isChecked = config.useCommaAsDecimalMark
|
||||||
|
settings_use_comma_as_decimal_mark_holder.setOnClickListener {
|
||||||
|
settings_use_comma_as_decimal_mark.toggle()
|
||||||
|
config.useCommaAsDecimalMark = settings_use_comma_as_decimal_mark.isChecked
|
||||||
|
updateWidgets()
|
||||||
|
ensureBackgroundThread {
|
||||||
|
applicationContext.calculatorDB.deleteHistory()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun setupCustomizeWidgetColors() {
|
private fun setupCustomizeWidgetColors() {
|
||||||
settings_customize_widget_colors_holder.setOnClickListener {
|
settings_customize_widget_colors_holder.setOnClickListener {
|
||||||
Intent(this, WidgetConfigureActivity::class.java).apply {
|
Intent(this, WidgetConfigureActivity::class.java).apply {
|
||||||
|
@ -1,12 +1,16 @@
|
|||||||
package com.simplemobiletools.calculator.extensions
|
package com.simplemobiletools.calculator.extensions
|
||||||
|
|
||||||
|
import android.appwidget.AppWidgetManager
|
||||||
|
import android.content.ComponentName
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.Button
|
import android.widget.Button
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import com.simplemobiletools.calculator.helpers.Config
|
|
||||||
import com.simplemobiletools.calculator.interfaces.CalculatorDao
|
|
||||||
import com.simplemobiletools.calculator.databases.CalculatorDatabase
|
import com.simplemobiletools.calculator.databases.CalculatorDatabase
|
||||||
|
import com.simplemobiletools.calculator.helpers.Config
|
||||||
|
import com.simplemobiletools.calculator.helpers.MyWidgetProvider
|
||||||
|
import com.simplemobiletools.calculator.interfaces.CalculatorDao
|
||||||
|
|
||||||
val Context.config: Config get() = Config.newInstance(applicationContext)
|
val Context.config: Config get() = Config.newInstance(applicationContext)
|
||||||
|
|
||||||
@ -16,11 +20,23 @@ val Context.calculatorDB: CalculatorDao get() = CalculatorDatabase.getInstance(a
|
|||||||
fun Context.updateViewColors(viewGroup: ViewGroup, textColor: Int) {
|
fun Context.updateViewColors(viewGroup: ViewGroup, textColor: Int) {
|
||||||
val cnt = viewGroup.childCount
|
val cnt = viewGroup.childCount
|
||||||
(0 until cnt).map { viewGroup.getChildAt(it) }
|
(0 until cnt).map { viewGroup.getChildAt(it) }
|
||||||
.forEach {
|
.forEach {
|
||||||
when (it) {
|
when (it) {
|
||||||
is TextView -> it.setTextColor(textColor)
|
is TextView -> it.setTextColor(textColor)
|
||||||
is Button -> it.setTextColor(textColor)
|
is Button -> it.setTextColor(textColor)
|
||||||
is ViewGroup -> updateViewColors(it, textColor)
|
is ViewGroup -> updateViewColors(it, textColor)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Context.updateWidgets() {
|
||||||
|
val widgetIDs = AppWidgetManager.getInstance(applicationContext)?.getAppWidgetIds(ComponentName(applicationContext, MyWidgetProvider::class.java))
|
||||||
|
?: return
|
||||||
|
if (widgetIDs.isNotEmpty()) {
|
||||||
|
Intent(applicationContext, MyWidgetProvider::class.java).apply {
|
||||||
|
action = AppWidgetManager.ACTION_APPWIDGET_UPDATE
|
||||||
|
putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, widgetIDs)
|
||||||
|
sendBroadcast(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,12 @@ import com.simplemobiletools.commons.extensions.toast
|
|||||||
import net.objecthunter.exp4j.ExpressionBuilder
|
import net.objecthunter.exp4j.ExpressionBuilder
|
||||||
import java.math.BigDecimal
|
import java.math.BigDecimal
|
||||||
|
|
||||||
class CalculatorImpl(calculator: Calculator, private val context: Context) {
|
class CalculatorImpl(
|
||||||
|
calculator: Calculator,
|
||||||
|
private val context: Context,
|
||||||
|
private var decimalSeparator: String = DOT,
|
||||||
|
private var groupingSeparator: String = COMMA
|
||||||
|
) {
|
||||||
private var callback: Calculator? = calculator
|
private var callback: Calculator? = calculator
|
||||||
|
|
||||||
private var baseValue = 0.0
|
private var baseValue = 0.0
|
||||||
@ -20,6 +25,10 @@ class CalculatorImpl(calculator: Calculator, private val context: Context) {
|
|||||||
private val operationsRegex = "[-+×÷^%√]".toPattern()
|
private val operationsRegex = "[-+×÷^%√]".toPattern()
|
||||||
private val numbersRegex = "[^0-9,.]".toRegex()
|
private val numbersRegex = "[^0-9,.]".toRegex()
|
||||||
|
|
||||||
|
private val formatter = NumberFormatHelper(
|
||||||
|
decimalSeparator = decimalSeparator, groupingSeparator = groupingSeparator
|
||||||
|
)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
showNewResult("0")
|
showNewResult("0")
|
||||||
}
|
}
|
||||||
@ -35,21 +44,21 @@ class CalculatorImpl(calculator: Calculator, private val context: Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun zeroClicked() {
|
private fun zeroClicked() {
|
||||||
val valueToCheck = inputDisplayedFormula.trimStart('-').replace(",", "")
|
val valueToCheck = inputDisplayedFormula.trimStart('-').removeGroupSeparator()
|
||||||
val value = valueToCheck.substring(valueToCheck.indexOfAny(operations) + 1)
|
val value = valueToCheck.substring(valueToCheck.indexOfAny(operations) + 1)
|
||||||
if (value != "0" || value.contains(".")) {
|
if (value != "0" || value.contains(decimalSeparator)) {
|
||||||
addDigit(0)
|
addDigit(0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun decimalClicked() {
|
private fun decimalClicked() {
|
||||||
val valueToCheck = inputDisplayedFormula.trimStart('-').replace(",", "")
|
val valueToCheck = inputDisplayedFormula.trimStart('-').replace(groupingSeparator, "")
|
||||||
val value = valueToCheck.substring(valueToCheck.indexOfAny(operations) + 1)
|
val value = valueToCheck.substring(valueToCheck.indexOfAny(operations) + 1)
|
||||||
if (!value.contains(".")) {
|
if (!value.contains(decimalSeparator)) {
|
||||||
when {
|
when {
|
||||||
value == "0" && !valueToCheck.contains(operationsRegex.toRegex()) -> inputDisplayedFormula = "0."
|
value == "0" && !valueToCheck.contains(operationsRegex.toRegex()) -> inputDisplayedFormula = "0$decimalSeparator"
|
||||||
value == "" -> inputDisplayedFormula += "0."
|
value == "" -> inputDisplayedFormula += "0$decimalSeparator"
|
||||||
else -> inputDisplayedFormula += "."
|
else -> inputDisplayedFormula += decimalSeparator
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,10 +69,13 @@ class CalculatorImpl(calculator: Calculator, private val context: Context) {
|
|||||||
private fun addThousandsDelimiter() {
|
private fun addThousandsDelimiter() {
|
||||||
val valuesToCheck = numbersRegex.split(inputDisplayedFormula).filter { it.trim().isNotEmpty() }
|
val valuesToCheck = numbersRegex.split(inputDisplayedFormula).filter { it.trim().isNotEmpty() }
|
||||||
valuesToCheck.forEach {
|
valuesToCheck.forEach {
|
||||||
var newString = Formatter.addGroupingSeparators(it)
|
var newString = formatter.addGroupingSeparators(it)
|
||||||
|
|
||||||
// allow writing numbers like 0.003
|
// allow writing numbers like 0.003
|
||||||
if (it.contains(".")) {
|
if (it.contains(decimalSeparator)) {
|
||||||
newString = newString.substringBefore(".") + ".${it.substringAfter(".")}"
|
val firstPart = newString.substringBefore(decimalSeparator)
|
||||||
|
val lastPart = it.substringAfter(decimalSeparator)
|
||||||
|
newString = "$firstPart$decimalSeparator$lastPart"
|
||||||
}
|
}
|
||||||
|
|
||||||
inputDisplayedFormula = inputDisplayedFormula.replace(it, newString)
|
inputDisplayedFormula = inputDisplayedFormula.replace(it, newString)
|
||||||
@ -86,7 +98,7 @@ class CalculatorImpl(calculator: Calculator, private val context: Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val lastChar = inputDisplayedFormula.last().toString()
|
val lastChar = inputDisplayedFormula.last().toString()
|
||||||
if (lastChar == ".") {
|
if (lastChar == decimalSeparator) {
|
||||||
inputDisplayedFormula = inputDisplayedFormula.dropLast(1)
|
inputDisplayedFormula = inputDisplayedFormula.dropLast(1)
|
||||||
} else if (operations.contains(lastChar)) {
|
} else if (operations.contains(lastChar)) {
|
||||||
inputDisplayedFormula = inputDisplayedFormula.dropLast(1)
|
inputDisplayedFormula = inputDisplayedFormula.dropLast(1)
|
||||||
@ -137,7 +149,7 @@ class CalculatorImpl(calculator: Calculator, private val context: Context) {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!inputDisplayedFormula.trimStart('-').any { it.toString() in operations } && inputDisplayedFormula.replace(",", "").toDouble() != 0.0) {
|
if (!inputDisplayedFormula.trimStart('-').any { it.toString() in operations } && inputDisplayedFormula.removeGroupSeparator().toDouble() != 0.0) {
|
||||||
inputDisplayedFormula = if (inputDisplayedFormula.first() == '-') {
|
inputDisplayedFormula = if (inputDisplayedFormula.first() == '-') {
|
||||||
inputDisplayedFormula.substring(1)
|
inputDisplayedFormula.substring(1)
|
||||||
} else {
|
} else {
|
||||||
@ -185,7 +197,7 @@ class CalculatorImpl(calculator: Calculator, private val context: Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun getSecondValue(): Double {
|
private fun getSecondValue(): Double {
|
||||||
val valueToCheck = inputDisplayedFormula.trimStart('-').replace(",", "")
|
val valueToCheck = inputDisplayedFormula.trimStart('-').removeGroupSeparator()
|
||||||
var value = valueToCheck.substring(valueToCheck.indexOfAny(operations) + 1)
|
var value = valueToCheck.substring(valueToCheck.indexOfAny(operations) + 1)
|
||||||
if (value == "") {
|
if (value == "") {
|
||||||
value = "0"
|
value = "0"
|
||||||
@ -205,23 +217,28 @@ class CalculatorImpl(calculator: Calculator, private val context: Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (lastKey != EQUALS) {
|
if (lastKey != EQUALS) {
|
||||||
val valueToCheck = inputDisplayedFormula.trimStart('-').replace(",", "")
|
val valueToCheck = inputDisplayedFormula.trimStart('-').removeGroupSeparator()
|
||||||
val parts = valueToCheck.split(operationsRegex).filter { it != "" }
|
val parts = valueToCheck.split(operationsRegex).filter { it != "" }
|
||||||
if (parts.isEmpty()) {
|
if (parts.isEmpty()) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
baseValue = Formatter.stringToDouble(parts.first())
|
baseValue = parts.first().toDouble()
|
||||||
if (inputDisplayedFormula.startsWith("-")) {
|
if (inputDisplayedFormula.startsWith("-")) {
|
||||||
baseValue *= -1
|
baseValue *= -1
|
||||||
}
|
}
|
||||||
|
|
||||||
secondValue = parts.getOrNull(1)?.replace(",", "")?.toDouble() ?: secondValue
|
secondValue = parts.getOrNull(1)?.toDouble() ?: secondValue
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lastOperation != "") {
|
if (lastOperation != "") {
|
||||||
val sign = getSign(lastOperation)
|
val sign = getSign(lastOperation)
|
||||||
val expression = "${baseValue.format()}$sign${secondValue.format()}".replace("√", "sqrt").replace("×", "*").replace("÷", "/")
|
val formattedBaseValue = baseValue.format().removeGroupSeparator()
|
||||||
|
val formatterSecondValue = secondValue.format().removeGroupSeparator()
|
||||||
|
val expression = "$formattedBaseValue$sign$formatterSecondValue"
|
||||||
|
.replace("√", "sqrt")
|
||||||
|
.replace("×", "*")
|
||||||
|
.replace("÷", "/")
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (sign == "÷" && secondValue == 0.0) {
|
if (sign == "÷" && secondValue == 0.0) {
|
||||||
@ -229,16 +246,11 @@ class CalculatorImpl(calculator: Calculator, private val context: Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sign == "%") {
|
|
||||||
val second = secondValue / 100f
|
|
||||||
"${baseValue.format()}*${second.format()}".replace("√", "sqrt").replace("×", "*").replace("÷", "/")
|
|
||||||
}
|
|
||||||
|
|
||||||
// handle percents manually, it doesn't seem to be possible via net.objecthunter:exp4j. "%" is used only for modulo there
|
// handle percents manually, it doesn't seem to be possible via net.objecthunter:exp4j. "%" is used only for modulo there
|
||||||
// handle cases like 10%200 here
|
// handle cases like 10%200 here
|
||||||
val result = if (sign == "%") {
|
val result = if (sign == "%") {
|
||||||
val second = secondValue / 100f
|
val second = (secondValue / 100f).format().removeGroupSeparator()
|
||||||
ExpressionBuilder("${baseValue.format().replace(",", "")}*${second.format()}").build().evaluate()
|
ExpressionBuilder("$formattedBaseValue*$second").build().evaluate()
|
||||||
} else {
|
} else {
|
||||||
// avoid Double rounding errors at expressions like 5250,74 + 14,98
|
// avoid Double rounding errors at expressions like 5250,74 + 14,98
|
||||||
if (sign == "+" || sign == "-") {
|
if (sign == "+" || sign == "-") {
|
||||||
@ -250,7 +262,7 @@ class CalculatorImpl(calculator: Calculator, private val context: Context) {
|
|||||||
}
|
}
|
||||||
bigDecimalResult.toDouble()
|
bigDecimalResult.toDouble()
|
||||||
} else {
|
} else {
|
||||||
ExpressionBuilder(expression.replace(",", "")).build().evaluate()
|
ExpressionBuilder(expression).build().evaluate()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -260,11 +272,14 @@ class CalculatorImpl(calculator: Calculator, private val context: Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
showNewResult(result.format())
|
showNewResult(result.format())
|
||||||
baseValue = result
|
val newFormula = "${baseValue.format()}$sign${secondValue.format()}"
|
||||||
val newFormula = expression.replace("sqrt", "√").replace("*", "×").replace("/", "÷")
|
HistoryHelper(context).insertOrUpdateHistoryEntry(
|
||||||
HistoryHelper(context).insertOrUpdateHistoryEntry(History(null, newFormula, result.format(), System.currentTimeMillis()))
|
History(id = null, formula = newFormula, result = result.format(), timestamp = System.currentTimeMillis())
|
||||||
inputDisplayedFormula = result.format()
|
)
|
||||||
showNewFormula(newFormula)
|
showNewFormula(newFormula)
|
||||||
|
|
||||||
|
inputDisplayedFormula = result.format()
|
||||||
|
baseValue = result
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
context.toast(R.string.unknown_error_occurred)
|
context.toast(R.string.unknown_error_occurred)
|
||||||
}
|
}
|
||||||
@ -317,19 +332,13 @@ class CalculatorImpl(calculator: Calculator, private val context: Context) {
|
|||||||
}
|
}
|
||||||
val lastValue = newValue.last().toString()
|
val lastValue = newValue.last().toString()
|
||||||
lastKey = when {
|
lastKey = when {
|
||||||
operations.contains(lastValue) -> {
|
operations.contains(lastValue) -> CLEAR
|
||||||
CLEAR
|
lastValue == decimalSeparator -> DECIMAL
|
||||||
}
|
else -> DIGIT
|
||||||
lastValue == "." -> {
|
|
||||||
DECIMAL
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
DIGIT
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
newValue = newValue.trimEnd(',')
|
newValue = newValue.trimEnd(groupingSeparator.single())
|
||||||
inputDisplayedFormula = newValue
|
inputDisplayedFormula = newValue
|
||||||
addThousandsDelimiter()
|
addThousandsDelimiter()
|
||||||
showNewResult(inputDisplayedFormula)
|
showNewResult(inputDisplayedFormula)
|
||||||
@ -391,4 +400,19 @@ class CalculatorImpl(calculator: Calculator, private val context: Context) {
|
|||||||
addThousandsDelimiter()
|
addThousandsDelimiter()
|
||||||
showNewResult(inputDisplayedFormula)
|
showNewResult(inputDisplayedFormula)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun updateSeparators(decimalSeparator: String, groupingSeparator: String) {
|
||||||
|
if (this.decimalSeparator != decimalSeparator || this.groupingSeparator != groupingSeparator) {
|
||||||
|
this.decimalSeparator = decimalSeparator
|
||||||
|
this.groupingSeparator = groupingSeparator
|
||||||
|
formatter.decimalSeparator = decimalSeparator
|
||||||
|
formatter.groupingSeparator = groupingSeparator
|
||||||
|
// future: maybe update the formulas with new separators instead of resetting the whole thing
|
||||||
|
handleReset()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Double.format() = formatter.doubleToString(this)
|
||||||
|
|
||||||
|
private fun String.removeGroupSeparator() = formatter.removeGroupingSeparator(this)
|
||||||
}
|
}
|
||||||
|
@ -7,4 +7,8 @@ class Config(context: Context) : BaseConfig(context) {
|
|||||||
companion object {
|
companion object {
|
||||||
fun newInstance(context: Context) = Config(context)
|
fun newInstance(context: Context) = Config(context)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var useCommaAsDecimalMark: Boolean
|
||||||
|
get() = prefs.getBoolean(USE_COMMA_AS_DECIMAL_MARK, false)
|
||||||
|
set(useCommaAsDecimalMark) = prefs.edit().putBoolean(USE_COMMA_AS_DECIMAL_MARK, useCommaAsDecimalMark).apply()
|
||||||
}
|
}
|
||||||
|
@ -24,3 +24,9 @@ const val SIX = "six"
|
|||||||
const val SEVEN = "seven"
|
const val SEVEN = "seven"
|
||||||
const val EIGHT = "eight"
|
const val EIGHT = "eight"
|
||||||
const val NINE = "nine"
|
const val NINE = "nine"
|
||||||
|
|
||||||
|
const val DOT = "."
|
||||||
|
const val COMMA = ","
|
||||||
|
|
||||||
|
// shared prefs
|
||||||
|
const val USE_COMMA_AS_DECIMAL_MARK = "use_comma_as_decimal_mark"
|
||||||
|
@ -1,25 +0,0 @@
|
|||||||
package com.simplemobiletools.calculator.helpers
|
|
||||||
|
|
||||||
import java.text.DecimalFormat
|
|
||||||
import java.text.DecimalFormatSymbols
|
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
object Formatter {
|
|
||||||
fun doubleToString(d: Double): String {
|
|
||||||
val symbols = DecimalFormatSymbols(Locale.US)
|
|
||||||
symbols.decimalSeparator = '.'
|
|
||||||
symbols.groupingSeparator = ','
|
|
||||||
|
|
||||||
val formatter = DecimalFormat()
|
|
||||||
formatter.maximumFractionDigits = 12
|
|
||||||
formatter.decimalFormatSymbols = symbols
|
|
||||||
formatter.isGroupingUsed = true
|
|
||||||
return formatter.format(d)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun stringToDouble(str: String) = str.replace(",", "").toDouble()
|
|
||||||
|
|
||||||
fun addGroupingSeparators(str: String) = doubleToString(stringToDouble(str))
|
|
||||||
}
|
|
||||||
|
|
||||||
fun Double.format(): String = Formatter.doubleToString(this)
|
|
@ -17,6 +17,9 @@ import com.simplemobiletools.commons.extensions.setText
|
|||||||
class MyWidgetProvider : AppWidgetProvider(), Calculator {
|
class MyWidgetProvider : AppWidgetProvider(), Calculator {
|
||||||
companion object {
|
companion object {
|
||||||
private var calc: CalculatorImpl? = null
|
private var calc: CalculatorImpl? = null
|
||||||
|
private var storedUseCommaAsDecimalMark = false
|
||||||
|
private var decimalSeparator = DOT
|
||||||
|
private var groupingSeparator = COMMA
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray) {
|
override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray) {
|
||||||
@ -53,6 +56,7 @@ class MyWidgetProvider : AppWidgetProvider(), Calculator {
|
|||||||
views.applyColorFilter(R.id.widget_background, config.widgetBgColor)
|
views.applyColorFilter(R.id.widget_background, config.widgetBgColor)
|
||||||
|
|
||||||
updateTextColors(views, config.widgetTextColor)
|
updateTextColors(views, config.widgetTextColor)
|
||||||
|
setupDecimalSeparator(views, config.useCommaAsDecimalMark)
|
||||||
appWidgetManager.updateAppWidget(it, views)
|
appWidgetManager.updateAppWidget(it, views)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -97,7 +101,7 @@ class MyWidgetProvider : AppWidgetProvider(), Calculator {
|
|||||||
|
|
||||||
private fun myAction(action: String, context: Context) {
|
private fun myAction(action: String, context: Context) {
|
||||||
if (calc == null) {
|
if (calc == null) {
|
||||||
calc = CalculatorImpl(this, context)
|
calc = CalculatorImpl(this, context, decimalSeparator, groupingSeparator)
|
||||||
}
|
}
|
||||||
|
|
||||||
when (action) {
|
when (action) {
|
||||||
@ -141,4 +145,17 @@ class MyWidgetProvider : AppWidgetProvider(), Calculator {
|
|||||||
super.onDeleted(context, appWidgetIds)
|
super.onDeleted(context, appWidgetIds)
|
||||||
calc = null
|
calc = null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun setupDecimalSeparator(views: RemoteViews, useCommaAsDecimalMark: Boolean) {
|
||||||
|
storedUseCommaAsDecimalMark = useCommaAsDecimalMark
|
||||||
|
if (storedUseCommaAsDecimalMark) {
|
||||||
|
decimalSeparator = COMMA
|
||||||
|
groupingSeparator = DOT
|
||||||
|
} else {
|
||||||
|
decimalSeparator = DOT
|
||||||
|
groupingSeparator = COMMA
|
||||||
|
}
|
||||||
|
calc?.updateSeparators(decimalSeparator, groupingSeparator)
|
||||||
|
views.setTextViewText(R.id.btn_decimal, decimalSeparator)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,31 @@
|
|||||||
|
package com.simplemobiletools.calculator.helpers
|
||||||
|
|
||||||
|
import java.text.DecimalFormat
|
||||||
|
import java.text.DecimalFormatSymbols
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
class NumberFormatHelper(
|
||||||
|
var decimalSeparator: String = DOT,
|
||||||
|
var groupingSeparator: String = COMMA
|
||||||
|
) {
|
||||||
|
|
||||||
|
fun doubleToString(d: Double): String {
|
||||||
|
val symbols = DecimalFormatSymbols(Locale.US)
|
||||||
|
symbols.decimalSeparator = decimalSeparator.single()
|
||||||
|
symbols.groupingSeparator = groupingSeparator.single()
|
||||||
|
|
||||||
|
val formatter = DecimalFormat()
|
||||||
|
formatter.maximumFractionDigits = 12
|
||||||
|
formatter.decimalFormatSymbols = symbols
|
||||||
|
formatter.isGroupingUsed = true
|
||||||
|
return formatter.format(d)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addGroupingSeparators(str: String): String {
|
||||||
|
return doubleToString(removeGroupingSeparator(str).toDouble())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun removeGroupingSeparator(str: String): String {
|
||||||
|
return str.replace(groupingSeparator, "").replace(decimalSeparator, DOT)
|
||||||
|
}
|
||||||
|
}
|
@ -126,7 +126,7 @@
|
|||||||
style="@style/SettingsHolderCheckboxStyle"
|
style="@style/SettingsHolderCheckboxStyle"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:background="@drawable/ripple_bottom_corners">
|
android:background="@drawable/ripple_background">
|
||||||
|
|
||||||
<com.simplemobiletools.commons.views.MyAppCompatCheckbox
|
<com.simplemobiletools.commons.views.MyAppCompatCheckbox
|
||||||
android:id="@+id/settings_prevent_phone_from_sleeping"
|
android:id="@+id/settings_prevent_phone_from_sleeping"
|
||||||
@ -136,6 +136,22 @@
|
|||||||
android:text="@string/prevent_phone_from_sleeping" />
|
android:text="@string/prevent_phone_from_sleeping" />
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:id="@+id/settings_use_comma_as_decimal_mark_holder"
|
||||||
|
style="@style/SettingsHolderCheckboxStyle"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@drawable/ripple_bottom_corners">
|
||||||
|
|
||||||
|
<com.simplemobiletools.commons.views.MyAppCompatCheckbox
|
||||||
|
android:id="@+id/settings_use_comma_as_decimal_mark"
|
||||||
|
style="@style/SettingsCheckboxStyle"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/use_comma_as_decimal_mark" />
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user