LocalProfile allow more profiles

This commit is contained in:
Milos Kozak 2019-09-16 15:49:45 +02:00
parent 60a113bda6
commit da447b8afe
8 changed files with 298 additions and 96 deletions

View file

@ -145,8 +145,8 @@ public class PreferencesActivity extends PreferenceActivity implements SharedPre
if (!Config.NSCLIENT) { if (!Config.NSCLIENT) {
addPreferencesFromResource(R.xml.pref_password); addPreferencesFromResource(R.xml.pref_password);
} }
addPreferencesFromResource(R.xml.pref_general);
addPreferencesFromResource(R.xml.pref_age); addPreferencesFromResource(R.xml.pref_age);
addPreferencesFromResource(R.xml.pref_language);
addPreferencesFromResource(R.xml.pref_overview); addPreferencesFromResource(R.xml.pref_overview);

View file

@ -116,6 +116,10 @@ public class ProfileFunctions {
return getProfile(System.currentTimeMillis()); return getProfile(System.currentTimeMillis());
} }
public static String getSystemUnits() {
return SP.getString(R.string.key_units, Constants.MGDL);
}
public String getProfileUnits() { public String getProfileUnits() {
Profile profile = getProfile(); Profile profile = getProfile();
return profile != null ? profile.getUnits() : Constants.MGDL; return profile != null ? profile.getUnits() : Constants.MGDL;

View file

@ -7,19 +7,21 @@ import android.text.TextWatcher
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.AdapterView
import android.widget.ArrayAdapter
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.MainApp import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.events.EventInitializationChanged import info.nightscout.androidaps.events.EventInitializationChanged
import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions
import info.nightscout.androidaps.plugins.general.careportal.CareportalFragment import info.nightscout.androidaps.plugins.general.careportal.CareportalFragment
import info.nightscout.androidaps.plugins.general.careportal.Dialogs.NewNSTreatmentDialog import info.nightscout.androidaps.plugins.general.careportal.Dialogs.NewNSTreatmentDialog
import info.nightscout.androidaps.plugins.insulin.InsulinOrefBasePlugin.MIN_DIA import info.nightscout.androidaps.plugins.insulin.InsulinOrefBasePlugin.MIN_DIA
import info.nightscout.androidaps.utils.DecimalFormatter import info.nightscout.androidaps.utils.*
import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.SafeParse
import info.nightscout.androidaps.utils.TimeListEdit
import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable import io.reactivex.disposables.CompositeDisposable
import kotlinx.android.synthetic.main.localprofile_fragment.* import kotlinx.android.synthetic.main.localprofile_fragment.*
@ -29,6 +31,7 @@ class LocalProfileFragment : Fragment() {
private var disposable: CompositeDisposable = CompositeDisposable() private var disposable: CompositeDisposable = CompositeDisposable()
private var basalView: TimeListEdit? = null private var basalView: TimeListEdit? = null
private var spinner: SpinnerHelper? = null
private val save = Runnable { private val save = Runnable {
doEdit() doEdit()
@ -39,7 +42,7 @@ class LocalProfileFragment : Fragment() {
override fun afterTextChanged(s: Editable) {} override fun afterTextChanged(s: Editable) {}
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {} override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) { override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
LocalProfilePlugin.dia = SafeParse.stringToDouble(localprofile_dia.text.toString()) LocalProfilePlugin.currentProfile().dia = SafeParse.stringToDouble(localprofile_dia.text.toString())
doEdit() doEdit()
} }
} }
@ -57,35 +60,71 @@ class LocalProfileFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
build()
}
fun build() {
val pumpDescription = ConfigBuilderPlugin.getPlugin().activePump?.pumpDescription ?: return val pumpDescription = ConfigBuilderPlugin.getPlugin().activePump?.pumpDescription ?: return
val units = ProfileFunctions.getSystemUnits()
localprofile_dia.setParams(LocalProfilePlugin.dia, MIN_DIA, 12.0, 0.1, DecimalFormat("0.0"), false, localprofile_save, textWatch) localprofile_name.setText(LocalProfilePlugin.currentProfile().name)
TimeListEdit(context, view, R.id.localprofile_ic, MainApp.gs(R.string.nsprofileview_ic_label) + ":", LocalProfilePlugin.ic, null, 0.5, 50.0, 0.1, DecimalFormat("0.0"), save) localprofile_dia.setParams(LocalProfilePlugin.currentProfile().dia, HardLimits.MINDIA, HardLimits.MAXDIA, 0.1, DecimalFormat("0.0"), false, localprofile_save, textWatch)
TimeListEdit(context, view, R.id.localprofile_isf, MainApp.gs(R.string.nsprofileview_isf_label) + ":", LocalProfilePlugin.isf, null, 0.5, 500.0, 0.1, DecimalFormat("0.0"), save) TimeListEdit(context, view, R.id.localprofile_ic, MainApp.gs(R.string.nsprofileview_ic_label) + ":", LocalProfilePlugin.currentProfile().ic, null, HardLimits.MINIC, HardLimits.MAXIC, 0.1, DecimalFormat("0.0"), save)
basalView = TimeListEdit(context, view, R.id.localprofile_basal, MainApp.gs(R.string.nsprofileview_basal_label) + ": " + sumLabel(), LocalProfilePlugin.basal, null, pumpDescription.basalMinimumRate, 10.0, 0.01, DecimalFormat("0.00"), save) basalView = TimeListEdit(context, view, R.id.localprofile_basal, MainApp.gs(R.string.nsprofileview_basal_label) + ": " + sumLabel(), LocalProfilePlugin.currentProfile().basal, null, pumpDescription.basalMinimumRate, 10.0, 0.01, DecimalFormat("0.00"), save)
TimeListEdit(context, view, R.id.localprofile_target, MainApp.gs(R.string.nsprofileview_target_label) + ":", LocalProfilePlugin.targetLow, LocalProfilePlugin.targetHigh, 3.0, 200.0, 0.1, DecimalFormat("0.0"), save) if (units == Constants.MGDL) {
TimeListEdit(context, view, R.id.localprofile_isf, MainApp.gs(R.string.nsprofileview_isf_label) + ":", LocalProfilePlugin.currentProfile().isf, null, HardLimits.MINISF, HardLimits.MAXISF, 1.0, DecimalFormat("0"), save)
TimeListEdit(context, view, R.id.localprofile_target, MainApp.gs(R.string.nsprofileview_target_label) + ":", LocalProfilePlugin.currentProfile().targetLow, LocalProfilePlugin.currentProfile().targetHigh, HardLimits.VERY_HARD_LIMIT_TARGET_BG[0].toDouble(), HardLimits.VERY_HARD_LIMIT_TARGET_BG[1].toDouble(), 1.0, DecimalFormat("0"), save)
if (!pumpDescription.isTempBasalCapable) { } else {
localprofile_basal.visibility = View.GONE TimeListEdit(context, view, R.id.localprofile_isf, MainApp.gs(R.string.nsprofileview_isf_label) + ":", LocalProfilePlugin.currentProfile().isf, null, Profile.fromMgdlToUnits(HardLimits.MINISF, Constants.MMOL), Profile.fromMgdlToUnits(HardLimits.MAXISF, Constants.MMOL), 0.1, DecimalFormat("0.0"), save)
TimeListEdit(context, view, R.id.localprofile_target, MainApp.gs(R.string.nsprofileview_target_label) + ":", LocalProfilePlugin.currentProfile().targetLow, LocalProfilePlugin.currentProfile().targetHigh, Profile.fromMgdlToUnits(HardLimits.VERY_HARD_LIMIT_TARGET_BG[0].toDouble(), Constants.MMOL), Profile.fromMgdlToUnits(HardLimits.VERY_HARD_LIMIT_TARGET_BG[1].toDouble(), Constants.MMOL), 0.1, DecimalFormat("0.0"), save)
} }
localprofile_mgdl.isChecked = LocalProfilePlugin.mgdl // Spinner
localprofile_mmol.isChecked = LocalProfilePlugin.mmol spinner = SpinnerHelper(view?.findViewById(R.id.localprofile_spinner))
val profileList: ArrayList<CharSequence> = LocalProfilePlugin.profile?.profileList
?: ArrayList()
context?.let { context ->
val adapter = ArrayAdapter(context, R.layout.spinner_centered, profileList)
spinner?.adapter = adapter
spinner?.setSelection(LocalProfilePlugin.currentProfileIndex)
} ?: return
spinner?.setOnItemSelectedListener(object : AdapterView.OnItemSelectedListener {
override fun onNothingSelected(parent: AdapterView<*>?) {
}
localprofile_mgdl.setOnClickListener { override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
LocalProfilePlugin.mgdl = localprofile_mgdl.isChecked if (LocalProfilePlugin.isEdited) {
LocalProfilePlugin.mmol = !LocalProfilePlugin.mgdl context?.let { context ->
localprofile_mmol.isChecked = LocalProfilePlugin.mmol OKDialog.show(context, MainApp.gs(R.string.confirmation), MainApp.gs(R.string.doyouwantswitchprofile)) {
doEdit() LocalProfilePlugin.currentProfileIndex = position
build()
}
}
} else {
LocalProfilePlugin.currentProfileIndex = position
build()
}
}
})
localprofile_profile_add.setOnClickListener {
LocalProfilePlugin.addNewProfile()
build()
} }
localprofile_mmol.setOnClickListener {
LocalProfilePlugin.mmol = localprofile_mmol.isChecked localprofile_profile_remove.setOnClickListener {
LocalProfilePlugin.mgdl = !LocalProfilePlugin.mmol LocalProfilePlugin.removeCurrentProfile()
localprofile_mgdl.isChecked = LocalProfilePlugin.mgdl build()
doEdit()
} }
// this is probably not possible because it leads to invalid profile
// if (!pumpDescription.isTempBasalCapable) localprofile_basal.visibility = View.GONE
localprofile_mgdl.isChecked = LocalProfilePlugin.currentProfile().mgdl
localprofile_mmol.isChecked = !LocalProfilePlugin.currentProfile().mgdl
localprofile_mgdl.isEnabled = false
localprofile_mmol.isEnabled = false
localprofile_profileswitch.setOnClickListener { localprofile_profileswitch.setOnClickListener {
val newDialog = NewNSTreatmentDialog() val newDialog = NewNSTreatmentDialog()
val profileSwitch = CareportalFragment.PROFILESWITCHDIRECT val profileSwitch = CareportalFragment.PROFILESWITCHDIRECT
@ -96,13 +135,13 @@ class LocalProfileFragment : Fragment() {
localprofile_reset.setOnClickListener { localprofile_reset.setOnClickListener {
LocalProfilePlugin.loadSettings() LocalProfilePlugin.loadSettings()
localprofile_mgdl.isChecked = LocalProfilePlugin.mgdl localprofile_mgdl.isChecked = LocalProfilePlugin.currentProfile().mgdl
localprofile_mmol.isChecked = LocalProfilePlugin.mmol localprofile_mmol.isChecked = !LocalProfilePlugin.currentProfile().mgdl
localprofile_dia.setParams(LocalProfilePlugin.dia, MIN_DIA, 12.0, 0.1, DecimalFormat("0.0"), false, localprofile_save, textWatch) localprofile_dia.setParams(LocalProfilePlugin.currentProfile().dia, MIN_DIA, 12.0, 0.1, DecimalFormat("0.0"), false, localprofile_save, textWatch)
TimeListEdit(context, view, R.id.localprofile_ic, MainApp.gs(R.string.nsprofileview_ic_label) + ":", LocalProfilePlugin.ic, null, 0.5, 50.0, 0.1, DecimalFormat("0.0"), save) TimeListEdit(context, view, R.id.localprofile_ic, MainApp.gs(R.string.nsprofileview_ic_label) + ":", LocalProfilePlugin.currentProfile().ic, null, 0.5, 50.0, 0.1, DecimalFormat("0.0"), save)
TimeListEdit(context, view, R.id.localprofile_isf, MainApp.gs(R.string.nsprofileview_isf_label) + ":", LocalProfilePlugin.isf, null, 0.5, 500.0, 0.1, DecimalFormat("0.0"), save) TimeListEdit(context, view, R.id.localprofile_isf, MainApp.gs(R.string.nsprofileview_isf_label) + ":", LocalProfilePlugin.currentProfile().isf, null, 0.5, 500.0, 0.1, DecimalFormat("0.0"), save)
basalView = TimeListEdit(context, view, R.id.localprofile_basal, MainApp.gs(R.string.nsprofileview_basal_label) + ": " + sumLabel(), LocalProfilePlugin.basal, null, pumpDescription.basalMinimumRate, 10.0, 0.01, DecimalFormat("0.00"), save) basalView = TimeListEdit(context, view, R.id.localprofile_basal, MainApp.gs(R.string.nsprofileview_basal_label) + ": " + sumLabel(), LocalProfilePlugin.currentProfile().basal, null, pumpDescription.basalMinimumRate, 10.0, 0.01, DecimalFormat("0.00"), save)
TimeListEdit(context, view, R.id.localprofile_target, MainApp.gs(R.string.nsprofileview_target_label) + ":", LocalProfilePlugin.targetLow, LocalProfilePlugin.targetHigh, 3.0, 200.0, 0.1, DecimalFormat("0.0"), save) TimeListEdit(context, view, R.id.localprofile_target, MainApp.gs(R.string.nsprofileview_target_label) + ":", LocalProfilePlugin.currentProfile().targetLow, LocalProfilePlugin.currentProfile().targetHigh, 3.0, 200.0, 0.1, DecimalFormat("0.0"), save)
updateGUI() updateGUI()
} }

View file

@ -11,16 +11,17 @@ import info.nightscout.androidaps.interfaces.PluginType
import info.nightscout.androidaps.interfaces.ProfileInterface import info.nightscout.androidaps.interfaces.ProfileInterface
import info.nightscout.androidaps.logging.L import info.nightscout.androidaps.logging.L
import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.DecimalFormatter import info.nightscout.androidaps.utils.DecimalFormatter
import info.nightscout.androidaps.utils.SP import info.nightscout.androidaps.utils.SP
import org.json.JSONArray import org.json.JSONArray
import org.json.JSONException import org.json.JSONException
import org.json.JSONObject import org.json.JSONObject
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory
import java.util.*
import kotlin.collections.ArrayList
/**
* Created by mike on 05.08.2016.
*/
object LocalProfilePlugin : PluginBase(PluginDescription() object LocalProfilePlugin : PluginBase(PluginDescription()
.mainType(PluginType.PROFILE) .mainType(PluginType.PROFILE)
.fragmentClass(LocalProfileFragment::class.java.name) .fragmentClass(LocalProfileFragment::class.java.name)
@ -36,15 +37,28 @@ object LocalProfilePlugin : PluginBase(PluginDescription()
private const val DEFAULTARRAY = "[{\"time\":\"00:00\",\"timeAsSeconds\":0,\"value\":0}]" private const val DEFAULTARRAY = "[{\"time\":\"00:00\",\"timeAsSeconds\":0,\"value\":0}]"
class SingleProfile {
internal var name: String? = null
internal var mgdl: Boolean = false
internal var dia: Double = Constants.defaultDIA
internal var ic: JSONArray? = null
internal var isf: JSONArray? = null
internal var basal: JSONArray? = null
internal var targetLow: JSONArray? = null
internal var targetHigh: JSONArray? = null
}
var isEdited: Boolean = false var isEdited: Boolean = false
internal var mgdl: Boolean = false var profiles: ArrayList<SingleProfile> = ArrayList()
internal var mmol: Boolean = false
internal var dia: Double? = null internal var numOfProfiles = 0
internal var ic: JSONArray? = null internal var currentProfileIndex = 0
internal var isf: JSONArray? = null
internal var basal: JSONArray? = null init {
internal var targetLow: JSONArray? = null loadSettings()
internal var targetHigh: JSONArray? = null }
fun currentProfile() = profiles[currentProfileIndex]
@Synchronized @Synchronized
fun isValidEditState(): Boolean { fun isValidEditState(): Boolean {
@ -52,20 +66,22 @@ object LocalProfilePlugin : PluginBase(PluginDescription()
?: false ?: false
} }
init {
loadSettings()
}
@Synchronized @Synchronized
fun storeSettings() { fun storeSettings() {
SP.putBoolean(LOCAL_PROFILE + "mmol", mmol) for (i in 0 until numOfProfiles) {
SP.putBoolean(LOCAL_PROFILE + "mgdl", mgdl) profiles[i].run {
SP.putString(LOCAL_PROFILE + "dia", dia.toString()) val LOCAL_PROFILE_NUMBERED = LOCAL_PROFILE + "_" + i + "_"
SP.putString(LOCAL_PROFILE + "ic", ic.toString()) SP.putString(LOCAL_PROFILE_NUMBERED + "name", name)
SP.putString(LOCAL_PROFILE + "isf", isf.toString()) SP.putBoolean(LOCAL_PROFILE_NUMBERED + "mgdl", mgdl)
SP.putString(LOCAL_PROFILE + "basal", basal.toString()) SP.putDouble(LOCAL_PROFILE_NUMBERED + "dia", dia)
SP.putString(LOCAL_PROFILE + "targetlow", targetLow.toString()) SP.putString(LOCAL_PROFILE_NUMBERED + "ic", ic.toString())
SP.putString(LOCAL_PROFILE + "targethigh", targetHigh.toString()) SP.putString(LOCAL_PROFILE_NUMBERED + "isf", isf.toString())
SP.putString(LOCAL_PROFILE_NUMBERED + "basal", basal.toString())
SP.putString(LOCAL_PROFILE_NUMBERED + "targetlow", targetLow.toString())
SP.putString(LOCAL_PROFILE_NUMBERED + "targethigh", targetHigh.toString())
}
}
SP.putInt(LOCAL_PROFILE + "_profiles", numOfProfiles)
createAndStoreConvertedProfile() createAndStoreConvertedProfile()
isEdited = false isEdited = false
@ -76,61 +92,146 @@ object LocalProfilePlugin : PluginBase(PluginDescription()
@Synchronized @Synchronized
fun loadSettings() { fun loadSettings() {
if (SP.contains(LOCAL_PROFILE + "mgdl")) {
doConversion()
return
}
numOfProfiles = SP.getInt(LOCAL_PROFILE + "_profiles", 0)
profiles.clear()
numOfProfiles = Math.max(numOfProfiles, 1) // create at least one default profile if none exists
for (i in 0 until numOfProfiles) {
val p = SingleProfile()
val LOCAL_PROFILE_NUMBERED = LOCAL_PROFILE + "_" + i + "_"
p.name = SP.getString(LOCAL_PROFILE_NUMBERED + "name", LOCAL_PROFILE + i)
p.mgdl = SP.getBoolean(LOCAL_PROFILE_NUMBERED + "mgdl", false)
p.dia = SP.getDouble(LOCAL_PROFILE_NUMBERED + "dia", Constants.defaultDIA)
try {
p.ic = JSONArray(SP.getString(LOCAL_PROFILE_NUMBERED + "ic", DEFAULTARRAY))
} catch (e1: JSONException) {
try {
p.ic = JSONArray(DEFAULTARRAY)
} catch (ignored: JSONException) {
}
log.error("Exception", e1)
}
try {
p.isf = JSONArray(SP.getString(LOCAL_PROFILE_NUMBERED + "isf", DEFAULTARRAY))
} catch (e1: JSONException) {
try {
p.isf = JSONArray(DEFAULTARRAY)
} catch (ignored: JSONException) {
}
log.error("Exception", e1)
}
try {
p.basal = JSONArray(SP.getString(LOCAL_PROFILE_NUMBERED + "basal", DEFAULTARRAY))
} catch (e1: JSONException) {
try {
p.basal = JSONArray(DEFAULTARRAY)
} catch (ignored: JSONException) {
}
log.error("Exception", e1)
}
try {
p.targetLow = JSONArray(SP.getString(LOCAL_PROFILE_NUMBERED + "targetlow", DEFAULTARRAY))
} catch (e1: JSONException) {
try {
p.targetLow = JSONArray(DEFAULTARRAY)
} catch (ignored: JSONException) {
}
log.error("Exception", e1)
}
try {
p.targetHigh = JSONArray(SP.getString(LOCAL_PROFILE_NUMBERED + "targethigh", DEFAULTARRAY))
} catch (e1: JSONException) {
try {
p.targetHigh = JSONArray(DEFAULTARRAY)
} catch (ignored: JSONException) {
}
log.error("Exception", e1)
}
profiles.add(p)
}
isEdited = false
createAndStoreConvertedProfile()
}
@Synchronized
private fun doConversion() { // conversion from 2.3 to 2.4 format
if (L.isEnabled(L.PROFILE)) if (L.isEnabled(L.PROFILE))
log.debug("Loading stored settings") log.debug("Loading stored settings")
val p = SingleProfile()
mgdl = SP.getBoolean(LOCAL_PROFILE + "mgdl", false) p.mgdl = SP.getBoolean(LOCAL_PROFILE + "mgdl", ProfileFunctions.getSystemUnits() == Constants.MGDL)
mmol = SP.getBoolean(LOCAL_PROFILE + "mmol", true) p.dia = SP.getDouble(LOCAL_PROFILE + "dia", Constants.defaultDIA)
dia = SP.getDouble(LOCAL_PROFILE + "dia", Constants.defaultDIA)
try { try {
ic = JSONArray(SP.getString(LOCAL_PROFILE + "ic", DEFAULTARRAY)) p.ic = JSONArray(SP.getString(LOCAL_PROFILE + "ic", DEFAULTARRAY))
} catch (e1: JSONException) { } catch (e1: JSONException) {
try { try {
ic = JSONArray(DEFAULTARRAY) p.ic = JSONArray(DEFAULTARRAY)
} catch (ignored: JSONException) { } catch (ignored: JSONException) {
} }
} }
try { try {
isf = JSONArray(SP.getString(LOCAL_PROFILE + "isf", DEFAULTARRAY)) p.isf = JSONArray(SP.getString(LOCAL_PROFILE + "isf", DEFAULTARRAY))
} catch (e1: JSONException) { } catch (e1: JSONException) {
try { try {
isf = JSONArray(DEFAULTARRAY) p.isf = JSONArray(DEFAULTARRAY)
} catch (ignored: JSONException) { } catch (ignored: JSONException) {
} }
} }
try { try {
basal = JSONArray(SP.getString(LOCAL_PROFILE + "basal", DEFAULTARRAY)) p.basal = JSONArray(SP.getString(LOCAL_PROFILE + "basal", DEFAULTARRAY))
} catch (e1: JSONException) { } catch (e1: JSONException) {
try { try {
basal = JSONArray(DEFAULTARRAY) p.basal = JSONArray(DEFAULTARRAY)
} catch (ignored: JSONException) { } catch (ignored: JSONException) {
} }
} }
try { try {
targetLow = JSONArray(SP.getString(LOCAL_PROFILE + "targetlow", DEFAULTARRAY)) p.targetLow = JSONArray(SP.getString(LOCAL_PROFILE + "targetlow", DEFAULTARRAY))
} catch (e1: JSONException) { } catch (e1: JSONException) {
try { try {
targetLow = JSONArray(DEFAULTARRAY) p.targetLow = JSONArray(DEFAULTARRAY)
} catch (ignored: JSONException) { } catch (ignored: JSONException) {
} }
} }
try { try {
targetHigh = JSONArray(SP.getString(LOCAL_PROFILE + "targethigh", DEFAULTARRAY)) p.targetHigh = JSONArray(SP.getString(LOCAL_PROFILE + "targethigh", DEFAULTARRAY))
} catch (e1: JSONException) { } catch (e1: JSONException) {
try { try {
targetHigh = JSONArray(DEFAULTARRAY) p.targetHigh = JSONArray(DEFAULTARRAY)
} catch (ignored: JSONException) { } catch (ignored: JSONException) {
} }
} }
p.name = LOCAL_PROFILE
SP.remove(LOCAL_PROFILE + "mgdl")
SP.remove(LOCAL_PROFILE + "mmol")
SP.remove(LOCAL_PROFILE + "dia")
SP.remove(LOCAL_PROFILE + "ic")
SP.remove(LOCAL_PROFILE + "isf")
SP.remove(LOCAL_PROFILE + "basal")
SP.remove(LOCAL_PROFILE + "targetlow")
SP.remove(LOCAL_PROFILE + "targethigh")
currentProfileIndex = 0
numOfProfiles = 1
profiles.clear()
profiles.add(p)
storeSettings()
isEdited = false isEdited = false
createAndStoreConvertedProfile() createAndStoreConvertedProfile()
@ -178,22 +279,61 @@ object LocalProfilePlugin : PluginBase(PluginDescription()
rawProfile = createProfileStore() rawProfile = createProfileStore()
} }
fun addNewProfile() {
var free = 0
for (i in 1..10000) {
if (rawProfile?.getSpecificProfile(LOCAL_PROFILE + i) == null) {
free = i;
break
}
}
val p = SingleProfile()
p.name = LOCAL_PROFILE + free
p.mgdl = ProfileFunctions.getSystemUnits() == Constants.MGDL
p.dia = Constants.defaultDIA
p.ic = JSONArray(DEFAULTARRAY)
p.isf = JSONArray(DEFAULTARRAY)
p.basal = JSONArray(DEFAULTARRAY)
p.targetLow = JSONArray(DEFAULTARRAY)
p.targetHigh = JSONArray(DEFAULTARRAY)
profiles.add(p)
currentProfileIndex = profiles.size - 1
numOfProfiles++
createAndStoreConvertedProfile()
storeSettings()
}
fun removeCurrentProfile() {
profiles.removeAt(currentProfileIndex)
numOfProfiles--
if (profiles.size == 0) addNewProfile()
currentProfileIndex = 0
createAndStoreConvertedProfile()
storeSettings()
}
fun createProfileStore(): ProfileStore { fun createProfileStore(): ProfileStore {
val json = JSONObject() val json = JSONObject()
val store = JSONObject() val store = JSONObject()
val profile = JSONObject()
try { try {
json.put("defaultProfile", LOCAL_PROFILE) for (i in 0 until numOfProfiles) {
profiles[i].run {
val profile = JSONObject()
profile.put("dia", dia)
profile.put("carbratio", ic)
profile.put("sens", isf)
profile.put("basal", basal)
profile.put("target_low", targetLow)
profile.put("target_high", targetHigh)
profile.put("units", if (mgdl) Constants.MGDL else Constants.MMOL)
profile.put("timezone", TimeZone.getDefault().id)
store.put(name, profile)
}
}
json.put("defaultProfile", currentProfile().name)
json.put("startDate", DateUtil.toISOAsUTC(DateUtil.now()))
json.put("store", store) json.put("store", store)
profile.put("dia", dia)
profile.put("carbratio", ic)
profile.put("sens", isf)
profile.put("basal", basal)
profile.put("target_low", targetLow)
profile.put("target_high", targetHigh)
profile.put("units", if (mgdl) Constants.MGDL else Constants.MMOL)
store.put(LOCAL_PROFILE, profile)
} catch (e: JSONException) { } catch (e: JSONException) {
log.error("Unhandled exception", e) log.error("Unhandled exception", e)
} }
@ -202,11 +342,11 @@ object LocalProfilePlugin : PluginBase(PluginDescription()
} }
override fun getProfile(): ProfileStore? { override fun getProfile(): ProfileStore? {
return if (rawProfile?.defaultProfile?.isValid(MainApp.gs(R.string.localprofile)) != true) null else rawProfile return rawProfile
} }
override fun getUnits(): String { override fun getUnits(): String {
return if (mgdl) Constants.MGDL else Constants.MMOL return if (currentProfile().mgdl) Constants.MGDL else Constants.MMOL
} }
override fun getProfileName(): String { override fun getProfileName(): String {

View file

@ -35,32 +35,29 @@
android:textAppearance="?android:attr/textAppearanceMedium" /> android:textAppearance="?android:attr/textAppearanceMedium" />
<Spinner <Spinner
android:id="@+id/spinner" android:id="@+id/localprofile_spinner"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginStart="10dp" android:layout_marginStart="10dp"
android:layout_weight="1" /> android:layout_weight="1" />
<ImageView <ImageView
android:id="@+id/localprofile_profile_add" android:id="@+id/localprofile_profile_add"
android:layout_width="wrap_content" android:layout_width="35dp"
android:layout_height="wrap_content" android:layout_height="35dp"
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
android:layout_marginStart="15dp" android:layout_marginStart="15dp"
android:scaleX="2"
android:scaleY="2"
android:src="@drawable/add" android:src="@drawable/add"
android:contentDescription="@string/addnew" /> android:contentDescription="@string/addnew" />
<ImageView <ImageView
android:id="@+id/localprofile_profile_remove" android:id="@+id/localprofile_profile_remove"
android:layout_width="wrap_content" android:layout_width="35dp"
android:layout_height="wrap_content" android:layout_height="35dp"
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
android:layout_marginStart="15dp" android:layout_marginStart="15dp"
android:layout_marginEnd="10dp" android:layout_marginEnd="10dp"
android:scaleX="2"
android:scaleY="2"
android:src="@drawable/remove" android:src="@drawable/remove"
android:contentDescription="@string/remove_label"/> android:contentDescription="@string/remove_label"/>

View file

@ -10,6 +10,15 @@
<item>open</item> <item>open</item>
</string-array> </string-array>
<string-array name="unitsArray">
<item>mg/dL</item>
<item>mmol/L</item>
</string-array>
<string-array name="unitsValues" translatable="false">
<item>mg/dl</item>
<item>mmol</item>
</string-array>
<string-array name="languagesArray"> <string-array name="languagesArray">
<item>@string/en_lang</item> <item>@string/en_lang</item>
<item>@string/af_lang</item> <item>@string/af_lang</item>

View file

@ -1606,5 +1606,8 @@
<string name="unit_minute_short">min</string> <string name="unit_minute_short">min</string>
<string name="profile_name">Profile name:</string> <string name="profile_name">Profile name:</string>
<string name="selected_profile">Selected:</string> <string name="selected_profile">Selected:</string>
<string name="unitsnosemicolon">Units</string>
<string name="key_units" translatable="false">units</string>
<string name="doyouwantswitchprofile">Do you want to switch profile and discard changes made to current profile?</string>
</resources> </resources>

View file

@ -1,13 +1,23 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory <PreferenceCategory
android:title="@string/configbuilder_general"> android:title="@string/configbuilder_general">
<ListPreference
android:title="@string/unitsnosemicolon"
android:defaultValue="mg/dl"
android:entries="@array/unitsArray"
android:entryValues="@array/unitsValues"
android:key="@string/key_units" />
<ListPreference <ListPreference
android:title="@string/language" android:title="@string/language"
android:defaultValue="en" android:defaultValue="en"
android:entries="@array/languagesArray" android:entries="@array/languagesArray"
android:entryValues="@array/languagesValues" android:entryValues="@array/languagesValues"
android:key="@string/key_language" /> android:key="@string/key_language" />
</PreferenceCategory> </PreferenceCategory>
</PreferenceScreen> </PreferenceScreen>