From e4c92c1863a582be9407d58b36ac89bacc75113d Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Wed, 31 Jul 2019 22:42:20 +0200 Subject: [PATCH 01/40] Bump 2.4-alpha2 --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 3335387f40..14e14bc8be 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -111,7 +111,7 @@ android { targetSdkVersion 28 multiDexEnabled true versionCode 1500 - version "2.4-dev" + version "2.4-alpha2" buildConfigField "String", "VERSION", '"' + version + '"' buildConfigField "String", "BUILDVERSION", '"' + generateGitBuild() + '-' + generateDate() + '"' buildConfigField "String", "REMOTE", '"' + generateGitRemote() + '"' From d827c10161c621664f5041b3ee586b8fe76a7707 Mon Sep 17 00:00:00 2001 From: Paulus Date: Thu, 1 Aug 2019 00:47:57 +0200 Subject: [PATCH 02/40] CR #1903 initial commit --- .../activities/HistoryBrowseActivity.java | 39 ++++++++++++------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/activities/HistoryBrowseActivity.java b/app/src/main/java/info/nightscout/androidaps/activities/HistoryBrowseActivity.java index a076608ed2..38e89a0f9b 100644 --- a/app/src/main/java/info/nightscout/androidaps/activities/HistoryBrowseActivity.java +++ b/app/src/main/java/info/nightscout/androidaps/activities/HistoryBrowseActivity.java @@ -2,9 +2,6 @@ package info.nightscout.androidaps.activities; import android.os.Bundle; import android.os.SystemClock; -import androidx.core.content.res.ResourcesCompat; -import androidx.appcompat.app.AppCompatActivity; -import androidx.appcompat.widget.PopupMenu; import android.text.SpannableString; import android.text.style.ForegroundColorSpan; import android.view.Menu; @@ -15,6 +12,10 @@ import android.widget.ImageButton; import android.widget.SeekBar; import android.widget.TextView; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.PopupMenu; +import androidx.core.content.res.ResourcesCompat; + import com.jjoe64.graphview.GraphView; import com.squareup.otto.Subscribe; import com.wdullaer.materialdatetimepicker.date.DatePickerDialog; @@ -36,13 +37,14 @@ import info.nightscout.androidaps.events.EventCustomCalculationFinished; import info.nightscout.androidaps.interfaces.PumpInterface; import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions; -import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin; -import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventAutosensCalculationFinished; -import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventIobCalculationProgress; import info.nightscout.androidaps.plugins.general.overview.OverviewFragment; import info.nightscout.androidaps.plugins.general.overview.OverviewPlugin; import info.nightscout.androidaps.plugins.general.overview.graphData.GraphData; +import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin; +import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventAutosensCalculationFinished; +import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventIobCalculationProgress; import info.nightscout.androidaps.utils.DateUtil; +import info.nightscout.androidaps.utils.SP; import info.nightscout.androidaps.utils.T; public class HistoryBrowseActivity extends AppCompatActivity { @@ -248,6 +250,15 @@ public class HistoryBrowseActivity extends AppCompatActivity { final boolean showPrediction = false; + showBasal = SP.getBoolean("hist_showbasals", true); + showIob = SP.getBoolean("hist_showiob", true); + showCob = SP.getBoolean("hist_showcob", true); + showDev = SP.getBoolean("hist_showdeviations", false); + showRat = SP.getBoolean("hist_showratios", false); + showActPrim = SP.getBoolean("hist_showactivityprimary", false); + showActSec = SP.getBoolean("hist_showactivitysecondary", false); + showDevslope = SP.getBoolean("hist_showdevslope", false); + int hoursToFetch; final long toTime; final long fromTime; @@ -453,21 +464,21 @@ public class HistoryBrowseActivity extends AppCompatActivity { popup.setOnMenuItemClickListener(item1 -> { if (item1.getItemId() == OverviewFragment.CHARTTYPE.BAS.ordinal()) { - showBasal = !item1.isChecked(); + SP.putBoolean("hist_showbasals", !item1.isChecked()); } else if (item1.getItemId() == OverviewFragment.CHARTTYPE.IOB.ordinal()) { - showIob = !item1.isChecked(); + SP.putBoolean("hist_showiob", !item1.isChecked()); } else if (item1.getItemId() == OverviewFragment.CHARTTYPE.COB.ordinal()) { - showCob = !item1.isChecked(); + SP.putBoolean("hist_showcob", !item1.isChecked()); } else if (item1.getItemId() == OverviewFragment.CHARTTYPE.DEV.ordinal()) { - showDev = !item1.isChecked(); + SP.putBoolean("hist_showdeviations", !item1.isChecked()); } else if (item1.getItemId() == OverviewFragment.CHARTTYPE.SEN.ordinal()) { - showRat = !item1.isChecked(); + SP.putBoolean("hist_showratios", !item1.isChecked()); } else if (item1.getItemId() == OverviewFragment.CHARTTYPE.ACTPRIM.ordinal()) { - showActPrim = !item1.isChecked(); + SP.putBoolean("hist_showactivityprimary", !item1.isChecked()); } else if (item1.getItemId() == OverviewFragment.CHARTTYPE.ACTSEC.ordinal()) { - showActSec = !item1.isChecked(); + SP.putBoolean("hist_showactivitysecondary", !item1.isChecked()); } else if (item1.getItemId() == OverviewFragment.CHARTTYPE.DEVSLOPE.ordinal()) { - showDevslope = !item1.isChecked(); + SP.putBoolean("hist_showdevslope", !item1.isChecked()); } updateGUI("onGraphCheckboxesCheckedChanged"); return true; From e0421b509c81a33f4a8a33741e8efafd7651eb07 Mon Sep 17 00:00:00 2001 From: Johannes Mockenhaupt Date: Wed, 21 Aug 2019 17:41:54 +0200 Subject: [PATCH 03/40] LocationService: invoke startForeground in onCreate(). --- .../info/nightscout/androidaps/services/LocationService.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/java/info/nightscout/androidaps/services/LocationService.java b/app/src/main/java/info/nightscout/androidaps/services/LocationService.java index feec4dcab8..485ad1823a 100644 --- a/app/src/main/java/info/nightscout/androidaps/services/LocationService.java +++ b/app/src/main/java/info/nightscout/androidaps/services/LocationService.java @@ -86,6 +86,8 @@ public class LocationService extends Service { @Override public void onCreate() { + super.onCreate(); + startForeground(PersistentNotificationPlugin.ONGOING_NOTIFICATION_ID, PersistentNotificationPlugin.getPlugin().updateNotification()); if (L.isEnabled(L.LOCATION)) log.debug("onCreate"); From 450a25c3b847c3eea1a2c607efe17b52b891643d Mon Sep 17 00:00:00 2001 From: Brian Quinion Date: Wed, 21 Aug 2019 17:38:01 +0100 Subject: [PATCH 04/40] Allow for Battery Optimization failing on some platforms --- .../setupwizard/SetupWizardActivity.java | 2 +- .../androidaps/utils/AndroidPermission.java | 36 +++++++++++++++---- app/src/main/res/values/strings.xml | 2 ++ 3 files changed, 32 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/setupwizard/SetupWizardActivity.java b/app/src/main/java/info/nightscout/androidaps/setupwizard/SetupWizardActivity.java index 3064228fd3..f998b343a2 100644 --- a/app/src/main/java/info/nightscout/androidaps/setupwizard/SetupWizardActivity.java +++ b/app/src/main/java/info/nightscout/androidaps/setupwizard/SetupWizardActivity.java @@ -226,7 +226,7 @@ public class SetupWizardActivity extends NoSplashAppCompatActivity { } @Override - protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == AndroidPermission.CASE_BATTERY) updateButtons(); diff --git a/app/src/main/java/info/nightscout/androidaps/utils/AndroidPermission.java b/app/src/main/java/info/nightscout/androidaps/utils/AndroidPermission.java index 7963ae0545..42f24dff69 100644 --- a/app/src/main/java/info/nightscout/androidaps/utils/AndroidPermission.java +++ b/app/src/main/java/info/nightscout/androidaps/utils/AndroidPermission.java @@ -3,7 +3,9 @@ package info.nightscout.androidaps.utils; import android.Manifest; import android.annotation.SuppressLint; import android.app.Activity; +import android.content.ActivityNotFoundException; import android.content.Context; +import android.content.DialogInterface; import android.content.Intent; import android.content.pm.PackageManager; import android.net.Uri; @@ -11,6 +13,7 @@ import android.os.Build; import android.os.PowerManager; import android.provider.Settings; +import androidx.appcompat.app.AlertDialog; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; @@ -45,10 +48,26 @@ public class AndroidPermission { ActivityCompat.requestPermissions(activity, permission, requestCode); } if (testBattery) { - Intent i = new Intent(); - i.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS); - i.setData(Uri.parse("package:" + activity.getPackageName())); - activity.startActivityForResult(i, CASE_BATTERY); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + try { + Intent i = new Intent(); + i.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS); + i.setData(Uri.parse("package:" + activity.getPackageName())); + activity.startActivityForResult(i, CASE_BATTERY); + } catch (ActivityNotFoundException e) { + SP.putBoolean(R.string.key_permission_battery_optimization_failed, true); + + AlertDialog.Builder alert = new AlertDialog.Builder(activity); + alert.setMessage(R.string.alert_dialog_permission_battery_optimization_failed); + alert.setPositiveButton(R.string.ok, null); + alert.setOnDismissListener(new DialogInterface.OnDismissListener() { + @Override + public void onDismiss(DialogInterface dialog) { + activity.recreate(); + } + }); + alert.show(); + } } } @@ -60,9 +79,12 @@ public class AndroidPermission { public static boolean permissionNotGranted(Context context, String permission) { boolean selfCheck = ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED; if (permission.equals(Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS)) { - PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE); - String packageName = context.getPackageName(); - selfCheck = selfCheck && powerManager.isIgnoringBatteryOptimizations(packageName); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M + && !SP.getBoolean(R.string.key_permission_battery_optimization_failed, false)) { + PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE); + String packageName = context.getPackageName(); + selfCheck = selfCheck && powerManager.isIgnoringBatteryOptimizations(packageName); + } } return !selfCheck; } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 2029c7023d..6a77b5acf7 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -38,6 +38,8 @@ DanaR Bluetooth device Always use basal absolute values Please reboot your phone or restart AndroidAPS from the System Settings \notherwise Android APS will not have logging (important to track and verify that the algorithms are working correctly)! + key_permission_battery_optimization_failed + This device does not appear to support battery optimization whitelisting - you may experience performance issues. Some buttons to quickly access common features Enter advanced log book entries. From d0335e56fa37ea3d7e4589d96840fedc30387df7 Mon Sep 17 00:00:00 2001 From: Brian Quinion Date: Wed, 21 Aug 2019 17:45:31 +0100 Subject: [PATCH 05/40] Allow for Battery Optimization failing on some platforms --- .../nightscout/androidaps/setupwizard/SetupWizardActivity.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/info/nightscout/androidaps/setupwizard/SetupWizardActivity.java b/app/src/main/java/info/nightscout/androidaps/setupwizard/SetupWizardActivity.java index f998b343a2..3064228fd3 100644 --- a/app/src/main/java/info/nightscout/androidaps/setupwizard/SetupWizardActivity.java +++ b/app/src/main/java/info/nightscout/androidaps/setupwizard/SetupWizardActivity.java @@ -226,7 +226,7 @@ public class SetupWizardActivity extends NoSplashAppCompatActivity { } @Override - public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == AndroidPermission.CASE_BATTERY) updateButtons(); From fb6bcfdccd42fb7991a7a0a226ab03b5607fdee6 Mon Sep 17 00:00:00 2001 From: Johannes Mockenhaupt Date: Thu, 22 Aug 2019 11:12:15 +0200 Subject: [PATCH 06/40] Log an uncaught exception before it crashes the app. --- app/src/main/java/info/nightscout/androidaps/MainApp.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/java/info/nightscout/androidaps/MainApp.java b/app/src/main/java/info/nightscout/androidaps/MainApp.java index f539f2e33f..f2edd23882 100644 --- a/app/src/main/java/info/nightscout/androidaps/MainApp.java +++ b/app/src/main/java/info/nightscout/androidaps/MainApp.java @@ -139,6 +139,8 @@ public class MainApp extends Application { sConstraintsChecker = new ConstraintChecker(); sDatabaseHelper = OpenHelperManager.getHelper(sInstance, DatabaseHelper.class); + Thread.setDefaultUncaughtExceptionHandler((thread, ex) -> log.error("Uncaught exception crashing app", ex)); + try { if (FabricPrivacy.fabricEnabled()) { Fabric.with(this, new Crashlytics()); From 75be27485cf41aedf7a469a303dc07244fa3555d Mon Sep 17 00:00:00 2001 From: Brian Quinion Date: Thu, 22 Aug 2019 10:29:13 +0100 Subject: [PATCH 07/40] Typo in battery optimization code --- .../java/info/nightscout/androidaps/utils/AndroidPermission.java | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/info/nightscout/androidaps/utils/AndroidPermission.java b/app/src/main/java/info/nightscout/androidaps/utils/AndroidPermission.java index 42f24dff69..3a9d8909b3 100644 --- a/app/src/main/java/info/nightscout/androidaps/utils/AndroidPermission.java +++ b/app/src/main/java/info/nightscout/androidaps/utils/AndroidPermission.java @@ -67,6 +67,7 @@ public class AndroidPermission { } }); alert.show(); + } } } } From 6ed0f9b40ece9d0c6d7391a6b4ef3401466e0aa1 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Thu, 22 Aug 2019 20:55:58 +0200 Subject: [PATCH 08/40] more detailed message --- app/src/main/res/values/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 2029c7023d..18006eb0b3 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1665,7 +1665,7 @@ No connection for %1$d day(s) %2$d hours %2$.1fg %3$.2fU]]> Bolus constraint applied: %2$.2fU to %3$.2fU]]> - !!!!! Slow carbs absorption detected: %2$d%% of time. Double check your calculation. COB can be really off !!!!!]]> + !!!!! Slow carbs absorption detected: %2$d%% of time. Double check your calculation. COB can be overestimated thus more insulin could be given !!!!!]]> %1$.0f / %2$d U From 40ffb6f19982d06249a126410ed380737e96ef36 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Thu, 22 Aug 2019 21:33:10 +0200 Subject: [PATCH 09/40] force use iob when cob is selected --- .../dialogs/EditQuickWizardDialog.java | 48 ++++++++++++++----- .../overview/dialogs/WizardDialog.java | 19 +++++++- 2 files changed, 54 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/dialogs/EditQuickWizardDialog.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/dialogs/EditQuickWizardDialog.java index 248ab30d7c..f4a689e34e 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/dialogs/EditQuickWizardDialog.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/dialogs/EditQuickWizardDialog.java @@ -8,6 +8,7 @@ import android.view.View; import android.view.ViewGroup; import android.view.Window; import android.view.WindowManager; +import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.EditText; import android.widget.Spinner; @@ -59,17 +60,17 @@ public class EditQuickWizardDialog extends DialogFragment implements View.OnClic getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN); View view = inflater.inflate(R.layout.overview_editquickwizard_dialog, container, false); - buttonEdit = (EditText) view.findViewById(R.id.overview_editquickwizard_button_edit); - carbsEdit = (EditText) view.findViewById(R.id.overview_editquickwizard_carbs_edit); - fromSpinner = (Spinner) view.findViewById(R.id.overview_editquickwizard_from_spinner); - toSpinner = (Spinner) view.findViewById(R.id.overview_editquickwizard_to_spinner); - useBGSpinner = (Spinner) view.findViewById(R.id.overview_editquickwizard_usebg_spinner); - useCOBSpinner = (Spinner) view.findViewById(R.id.overview_editquickwizard_usecob_spinner); - useBolusIOBSpinner = (Spinner) view.findViewById(R.id.overview_editquickwizard_usebolusiob_spinner); - useBasalIOBSpinner = (Spinner) view.findViewById(R.id.overview_editquickwizard_usebasaliob_spinner); - useTrendSpinner = (Spinner) view.findViewById(R.id.overview_editquickwizard_usetrend_spinner); - useSuperBolusSpinner = (Spinner) view.findViewById(R.id.overview_editquickwizard_usesuperbolus_spinner); - useTempTargetSpinner = (Spinner) view.findViewById(R.id.overview_editquickwizard_usetemptarget_spinner); + buttonEdit = view.findViewById(R.id.overview_editquickwizard_button_edit); + carbsEdit = view.findViewById(R.id.overview_editquickwizard_carbs_edit); + fromSpinner = view.findViewById(R.id.overview_editquickwizard_from_spinner); + toSpinner = view.findViewById(R.id.overview_editquickwizard_to_spinner); + useBGSpinner = view.findViewById(R.id.overview_editquickwizard_usebg_spinner); + useCOBSpinner = view.findViewById(R.id.overview_editquickwizard_usecob_spinner); + useBolusIOBSpinner = view.findViewById(R.id.overview_editquickwizard_usebolusiob_spinner); + useBasalIOBSpinner = view.findViewById(R.id.overview_editquickwizard_usebasaliob_spinner); + useTrendSpinner = view.findViewById(R.id.overview_editquickwizard_usetrend_spinner); + useSuperBolusSpinner = view.findViewById(R.id.overview_editquickwizard_usesuperbolus_spinner); + useTempTargetSpinner = view.findViewById(R.id.overview_editquickwizard_usetemptarget_spinner); view.findViewById(R.id.ok).setOnClickListener(this); view.findViewById(R.id.cancel).setOnClickListener(this); @@ -104,6 +105,19 @@ public class EditQuickWizardDialog extends DialogFragment implements View.OnClic setSelection(useSuperBolusSpinner, entry.useSuperBolus()); setSelection(useTempTargetSpinner, entry.useTempTarget()); + useCOBSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + @Override + public void onItemSelected(AdapterView parent, View view, int position, long id) { + processCob(); + } + + @Override + public void onNothingSelected(AdapterView parent) { + + } + }); + processCob(); + return view; } @@ -147,6 +161,18 @@ public class EditQuickWizardDialog extends DialogFragment implements View.OnClic } } + private void processCob() { + if (getSelection(useCOBSpinner) == QuickWizardEntry.YES) { + useBolusIOBSpinner.setEnabled(false); + useBasalIOBSpinner.setEnabled(false); + setSelection(useBolusIOBSpinner, QuickWizardEntry.YES); + setSelection(useBasalIOBSpinner, QuickWizardEntry.YES); + } else { + useBolusIOBSpinner.setEnabled(true); + useBasalIOBSpinner.setEnabled(true); + } + } + int getSelection(Spinner spinner) { String value = spinner.getSelectedItem().toString(); if (value.equals(MainApp.gs(R.string.yes))) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/dialogs/WizardDialog.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/dialogs/WizardDialog.java index fb903f3bae..6fb3768051 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/dialogs/WizardDialog.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/dialogs/WizardDialog.java @@ -3,8 +3,6 @@ package info.nightscout.androidaps.plugins.general.overview.dialogs; import android.app.Activity; import android.content.Context; import android.os.Bundle; -import androidx.fragment.app.DialogFragment; -import androidx.appcompat.app.AlertDialog; import android.text.Editable; import android.text.TextWatcher; import android.view.LayoutInflater; @@ -23,6 +21,8 @@ import android.widget.LinearLayout; import android.widget.Spinner; import android.widget.TextView; +import androidx.fragment.app.DialogFragment; + import com.squareup.otto.Subscribe; import org.slf4j.Logger; @@ -254,6 +254,7 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com editCarbTime.setValue(savedInstanceState.getDouble("editCarbTime")); editCorr.setValue(savedInstanceState.getDouble("editCorr")); } + processCobCheckBox(); return view; } @@ -261,9 +262,23 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { saveCheckedStates(); ttCheckbox.setEnabled(bgCheckbox.isChecked() && TreatmentsPlugin.getPlugin().getTempTargetFromHistory() != null); + if (buttonView.getId() == cobCheckbox.getId()) + processCobCheckBox(); calculateInsulin(); } + private void processCobCheckBox() { + if (cobCheckbox.isChecked()) { + bolusIobCheckbox.setEnabled(false); + basalIobCheckbox.setEnabled(false); + bolusIobCheckbox.setChecked(true); + basalIobCheckbox.setChecked(true); + } else { + bolusIobCheckbox.setEnabled(true); + basalIobCheckbox.setEnabled(true); + } + } + private void saveCheckedStates() { SP.putBoolean(MainApp.gs(R.string.key_wizard_include_cob), cobCheckbox.isChecked()); SP.putBoolean(MainApp.gs(R.string.key_wizard_include_trend_bg), bgtrendCheckbox.isChecked()); From 0a77fb9bcbd56509c06f916fe003f98620c60642 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Fri, 23 Aug 2019 16:31:30 +0200 Subject: [PATCH 10/40] implement percentage in wizard, refactoring to kotlin --- .../activities/HistoryBrowseActivity.java | 2 +- .../plugins/aps/loop/LoopPlugin.java | 2 +- .../overview/dialogs/WizardDialog.java | 465 ------------------ .../general/overview/dialogs/WizardDialog.kt | 344 +++++++++++++ .../iob/iobCobCalculator/IobCobThread.java | 2 + .../EventAutosensCalculationFinished.java | 16 - .../EventAutosensCalculationFinished.kt | 6 + .../treatments/dialogs/WizardInfoDialog.java | 86 ---- .../treatments/dialogs/WizardInfoDialog.kt | 70 +++ .../androidaps/utils/BolusWizard.kt | 1 + .../androidaps/utils/JsonHelper.java | 13 + .../res/layout/overview_wizard_dialog.xml | 14 +- .../layout/treatments_wizardinfo_dialog.xml | 37 +- app/src/main/res/values/strings.xml | 3 + app/src/main/res/xml/pref_overview.xml | 13 + 15 files changed, 503 insertions(+), 571 deletions(-) delete mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/general/overview/dialogs/WizardDialog.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/general/overview/dialogs/WizardDialog.kt delete mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/events/EventAutosensCalculationFinished.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/events/EventAutosensCalculationFinished.kt delete mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/treatments/dialogs/WizardInfoDialog.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/treatments/dialogs/WizardInfoDialog.kt diff --git a/app/src/main/java/info/nightscout/androidaps/activities/HistoryBrowseActivity.java b/app/src/main/java/info/nightscout/androidaps/activities/HistoryBrowseActivity.java index 75767ec974..e5639d2ba4 100644 --- a/app/src/main/java/info/nightscout/androidaps/activities/HistoryBrowseActivity.java +++ b/app/src/main/java/info/nightscout/androidaps/activities/HistoryBrowseActivity.java @@ -194,7 +194,7 @@ public class HistoryBrowseActivity extends NoSplashActivity { @Subscribe public void onStatusEvent(final EventAutosensCalculationFinished e) { - if (e.cause == eventCustomCalculationFinished) { + if (e.getCause() == eventCustomCalculationFinished) { log.debug("EventAutosensCalculationFinished"); runOnUiThread(() -> { synchronized (HistoryBrowseActivity.this) { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/aps/loop/LoopPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/aps/loop/LoopPlugin.java index e68bf9c30d..47a477f382 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/aps/loop/LoopPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/aps/loop/LoopPlugin.java @@ -155,7 +155,7 @@ public class LoopPlugin extends PluginBase { */ @Subscribe public void onStatusEvent(final EventAutosensCalculationFinished ev) { - if (!(ev.cause instanceof EventNewBG)) { + if (!(ev.getCause() instanceof EventNewBG)) { // Autosens calculation not triggered by a new BG return; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/dialogs/WizardDialog.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/dialogs/WizardDialog.java deleted file mode 100644 index 6fb3768051..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/dialogs/WizardDialog.java +++ /dev/null @@ -1,465 +0,0 @@ -package info.nightscout.androidaps.plugins.general.overview.dialogs; - -import android.app.Activity; -import android.content.Context; -import android.os.Bundle; -import android.text.Editable; -import android.text.TextWatcher; -import android.view.LayoutInflater; -import android.view.View; -import android.view.View.OnClickListener; -import android.view.ViewGroup; -import android.view.Window; -import android.view.WindowManager; -import android.widget.AdapterView; -import android.widget.ArrayAdapter; -import android.widget.Button; -import android.widget.CheckBox; -import android.widget.CompoundButton; -import android.widget.EditText; -import android.widget.LinearLayout; -import android.widget.Spinner; -import android.widget.TextView; - -import androidx.fragment.app.DialogFragment; - -import com.squareup.otto.Subscribe; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.text.DecimalFormat; -import java.util.ArrayList; - -import info.nightscout.androidaps.Constants; -import info.nightscout.androidaps.MainApp; -import info.nightscout.androidaps.R; -import info.nightscout.androidaps.data.IobTotal; -import info.nightscout.androidaps.data.Profile; -import info.nightscout.androidaps.data.ProfileStore; -import info.nightscout.androidaps.db.BgReading; -import info.nightscout.androidaps.db.DatabaseHelper; -import info.nightscout.androidaps.db.TempTarget; -import info.nightscout.androidaps.events.EventFeatureRunning; -import info.nightscout.androidaps.interfaces.Constraint; -import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin; -import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions; -import info.nightscout.androidaps.plugins.iob.iobCobCalculator.CobInfo; -import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin; -import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventAutosensCalculationFinished; -import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin; -import info.nightscout.androidaps.utils.BolusWizard; -import info.nightscout.androidaps.utils.DecimalFormatter; -import info.nightscout.androidaps.utils.NumberPicker; -import info.nightscout.androidaps.utils.SP; -import info.nightscout.androidaps.utils.SafeParse; -import info.nightscout.androidaps.utils.StringUtils; -import info.nightscout.androidaps.utils.ToastUtils; - -public class WizardDialog extends DialogFragment implements OnClickListener, CompoundButton.OnCheckedChangeListener, Spinner.OnItemSelectedListener { - private static Logger log = LoggerFactory.getLogger(WizardDialog.class); - - Button okButton; - TextView bg; - TextView bgInsulin; - TextView bgUnits; - CheckBox bgCheckbox; - CheckBox ttCheckbox; - TextView carbs; - TextView carbsInsulin; - TextView bolusIobInsulin; - TextView basalIobInsulin; - CheckBox bolusIobCheckbox; - CheckBox basalIobCheckbox; - TextView correctionInsulin; - TextView total; - Spinner profileSpinner; - CheckBox superbolusCheckbox; - TextView superbolus; - TextView superbolusInsulin; - CheckBox bgtrendCheckbox; - TextView bgTrend; - TextView bgTrendInsulin; - LinearLayout cobLayout; - CheckBox cobCheckbox; - TextView cob; - TextView cobInsulin; - - NumberPicker editBg; - NumberPicker editCarbs; - NumberPicker editCorr; - NumberPicker editCarbTime; - - LinearLayout notesLayout; - EditText notesEdit; - - Integer calculatedCarbs = 0; - BolusWizard wizard; - - Context context; - - //one shot guards - private boolean accepted; - private boolean okClicked; - - public WizardDialog() { - super(); - } - - @Override - public void onAttach(Context context) { - super.onAttach(context); - this.context = context; - } - - @Override - public void onDetach() { - super.onDetach(); - this.context = null; - } - - @Override - public void onResume() { - super.onResume(); - MainApp.bus().register(this); - MainApp.bus().post(new EventFeatureRunning(EventFeatureRunning.Feature.WIZARD)); - } - - @Override - public void onPause() { - super.onPause(); - MainApp.bus().unregister(this); - } - - @Override - public void onSaveInstanceState(Bundle savedInstanceState) { - savedInstanceState.putBoolean("bgCheckbox", bgCheckbox.isChecked()); - savedInstanceState.putBoolean("ttCheckbox", ttCheckbox.isChecked()); - savedInstanceState.putBoolean("bolusIobCheckbox", bolusIobCheckbox.isChecked()); - savedInstanceState.putBoolean("basalIobCheckbox", basalIobCheckbox.isChecked()); - savedInstanceState.putBoolean("bgtrendCheckbox", bgtrendCheckbox.isChecked()); - savedInstanceState.putBoolean("cobCheckbox", cobCheckbox.isChecked()); - savedInstanceState.putDouble("editBg", editBg.getValue()); - savedInstanceState.putDouble("editCarbs", editCarbs.getValue()); - savedInstanceState.putDouble("editCorr", editCorr.getValue()); - savedInstanceState.putDouble("editCarbTime", editCarbTime.getValue()); - super.onSaveInstanceState(savedInstanceState); - } - - - @Subscribe - public void onStatusEvent(final EventAutosensCalculationFinished e) { - Activity activity = getActivity(); - if (activity != null) - activity.runOnUiThread(new Runnable() { - @Override - public void run() { - calculateInsulin(); - } - }); - } - - final private TextWatcher textWatcher = new TextWatcher() { - @Override - public void afterTextChanged(Editable s) { - } - - @Override - public void beforeTextChanged(CharSequence s, int start, int count, int after) { - } - - @Override - public void onTextChanged(CharSequence s, int start, int before, int count) { - calculateInsulin(); - } - }; - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - View view = inflater.inflate(R.layout.overview_wizard_dialog, container, false); - - getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE); - getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN); - - okButton = (Button) view.findViewById(R.id.ok); - okButton.setOnClickListener(this); - view.findViewById(R.id.cancel).setOnClickListener(this); - - bg = (TextView) view.findViewById(R.id.treatments_wizard_bg); - bgInsulin = (TextView) view.findViewById(R.id.treatments_wizard_bginsulin); - bgUnits = (TextView) view.findViewById(R.id.treatments_wizard_bgunits); - carbs = (TextView) view.findViewById(R.id.treatments_wizard_carbs); - carbsInsulin = (TextView) view.findViewById(R.id.treatments_wizard_carbsinsulin); - bolusIobInsulin = (TextView) view.findViewById(R.id.treatments_wizard_bolusiobinsulin); - basalIobInsulin = (TextView) view.findViewById(R.id.treatments_wizard_basaliobinsulin); - correctionInsulin = (TextView) view.findViewById(R.id.treatments_wizard_correctioninsulin); - total = (TextView) view.findViewById(R.id.treatments_wizard_total); - superbolus = (TextView) view.findViewById(R.id.treatments_wizard_sb); - superbolusInsulin = (TextView) view.findViewById(R.id.treatments_wizard_sbinsulin); - - notesLayout = view.findViewById(R.id.treatments_wizard_notes_layout); - notesLayout.setVisibility(SP.getBoolean(R.string.key_show_notes_entry_dialogs, false) ? View.VISIBLE : View.GONE); - notesEdit = (EditText) view.findViewById(R.id.treatment_wizard_notes); - - bgTrend = (TextView) view.findViewById(R.id.treatments_wizard_bgtrend); - bgTrendInsulin = (TextView) view.findViewById(R.id.treatments_wizard_bgtrendinsulin); - cobLayout = (LinearLayout) view.findViewById(R.id.treatments_wizard_cob_layout); - cob = (TextView) view.findViewById(R.id.treatments_wizard_cob); - cobInsulin = (TextView) view.findViewById(R.id.treatments_wizard_cobinsulin); - - bgCheckbox = (CheckBox) view.findViewById(R.id.treatments_wizard_bgcheckbox); - ttCheckbox = (CheckBox) view.findViewById(R.id.treatments_wizard_ttcheckbox); - bgtrendCheckbox = (CheckBox) view.findViewById(R.id.treatments_wizard_bgtrendcheckbox); - cobCheckbox = (CheckBox) view.findViewById(R.id.treatments_wizard_cobcheckbox); - bolusIobCheckbox = (CheckBox) view.findViewById(R.id.treatments_wizard_bolusiobcheckbox); - basalIobCheckbox = (CheckBox) view.findViewById(R.id.treatments_wizard_basaliobcheckbox); - superbolusCheckbox = (CheckBox) view.findViewById(R.id.treatments_wizard_sbcheckbox); - loadCheckedStates(); - - bgCheckbox.setOnCheckedChangeListener(this); - ttCheckbox.setOnCheckedChangeListener(this); - bgtrendCheckbox.setOnCheckedChangeListener(this); - cobCheckbox.setOnCheckedChangeListener(this); - basalIobCheckbox.setOnCheckedChangeListener(this); - bolusIobCheckbox.setOnCheckedChangeListener(this); - superbolusCheckbox.setOnCheckedChangeListener(this); - - profileSpinner = (Spinner) view.findViewById(R.id.treatments_wizard_profile); - profileSpinner.setOnItemSelectedListener(this); - - editCarbTime = (NumberPicker) view.findViewById(R.id.treatments_wizard_carbtimeinput); - editCorr = (NumberPicker) view.findViewById(R.id.treatments_wizard_correctioninput); - editCarbs = (NumberPicker) view.findViewById(R.id.treatments_wizard_carbsinput); - editBg = (NumberPicker) view.findViewById(R.id.treatments_wizard_bginput); - - superbolusCheckbox.setVisibility(SP.getBoolean(R.string.key_usesuperbolus, false) ? View.VISIBLE : View.GONE); - - Integer maxCarbs = MainApp.getConstraintChecker().getMaxCarbsAllowed().value(); - Double maxCorrection = MainApp.getConstraintChecker().getMaxBolusAllowed().value(); - - editBg.setParams(0d, 0d, 500d, 0.1d, new DecimalFormat("0.0"), false, view.findViewById(R.id.ok), textWatcher); - editCarbs.setParams(0d, 0d, (double) maxCarbs, 1d, new DecimalFormat("0"), false, view.findViewById(R.id.ok), textWatcher); - double bolusstep = ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription().bolusStep; - editCorr.setParams(0d, -maxCorrection, maxCorrection, bolusstep, DecimalFormatter.pumpSupportedBolusFormat(), false, view.findViewById(R.id.ok), textWatcher); - editCarbTime.setParams(0d, -60d, 60d, 5d, new DecimalFormat("0"), false, view.findViewById(R.id.ok), textWatcher); - initDialog(); - - setCancelable(true); - getDialog().setCanceledOnTouchOutside(false); - //recovering state if there is something - if (savedInstanceState != null) { - editCarbs.setValue(savedInstanceState.getDouble("editCarbs")); - editBg.setValue(savedInstanceState.getDouble("editBg")); - editCarbTime.setValue(savedInstanceState.getDouble("editCarbTime")); - editCorr.setValue(savedInstanceState.getDouble("editCorr")); - } - processCobCheckBox(); - return view; - } - - @Override - public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { - saveCheckedStates(); - ttCheckbox.setEnabled(bgCheckbox.isChecked() && TreatmentsPlugin.getPlugin().getTempTargetFromHistory() != null); - if (buttonView.getId() == cobCheckbox.getId()) - processCobCheckBox(); - calculateInsulin(); - } - - private void processCobCheckBox() { - if (cobCheckbox.isChecked()) { - bolusIobCheckbox.setEnabled(false); - basalIobCheckbox.setEnabled(false); - bolusIobCheckbox.setChecked(true); - basalIobCheckbox.setChecked(true); - } else { - bolusIobCheckbox.setEnabled(true); - basalIobCheckbox.setEnabled(true); - } - } - - private void saveCheckedStates() { - SP.putBoolean(MainApp.gs(R.string.key_wizard_include_cob), cobCheckbox.isChecked()); - SP.putBoolean(MainApp.gs(R.string.key_wizard_include_trend_bg), bgtrendCheckbox.isChecked()); - } - - private void loadCheckedStates() { - bgtrendCheckbox.setChecked(SP.getBoolean(MainApp.gs(R.string.key_wizard_include_trend_bg), false)); - cobCheckbox.setChecked(SP.getBoolean(MainApp.gs(R.string.key_wizard_include_cob), false)); - } - - @Override - public void onItemSelected(AdapterView parent, View view, int position, long id) { - calculateInsulin(); - okButton.setVisibility(View.VISIBLE); - } - - @Override - public void onNothingSelected(AdapterView parent) { - ToastUtils.showToastInUiThread(context, MainApp.gs(R.string.noprofileselected)); - okButton.setVisibility(View.GONE); - } - - @Override - public synchronized void onClick(View view) { - switch (view.getId()) { - case R.id.ok: - if (okClicked) { - log.debug("guarding: ok already clicked"); - dismiss(); - return; - } - okClicked = true; - wizard.confirmAndExecute(context); - dismiss(); - break; - case R.id.cancel: - dismiss(); - break; - } - } - - private void initDialog() { - Profile profile = ProfileFunctions.getInstance().getProfile(); - ProfileStore profileStore = ConfigBuilderPlugin.getPlugin().getActiveProfileInterface() != null ? ConfigBuilderPlugin.getPlugin().getActiveProfileInterface().getProfile() : null; - - if (profile == null || profileStore == null) { - ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.noprofile)); - dismiss(); - return; - } - - ArrayList profileList; - profileList = profileStore.getProfileList(); - profileList.add(0, MainApp.gs(R.string.active)); - ArrayAdapter adapter = new ArrayAdapter<>(getContext(), - R.layout.spinner_centered, profileList); - - profileSpinner.setAdapter(adapter); - - String units = profile.getUnits(); - bgUnits.setText(units); - if (units.equals(Constants.MGDL)) editBg.setStep(1d); - else editBg.setStep(0.1d); - - // Set BG if not old - BgReading lastBg = DatabaseHelper.actualBg(); - - if (lastBg != null) { - editBg.setValue(lastBg.valueToUnits(units)); - } else { - editBg.setValue(0d); - } - ttCheckbox.setEnabled(TreatmentsPlugin.getPlugin().getTempTargetFromHistory() != null); - - // IOB calculation - TreatmentsPlugin.getPlugin().updateTotalIOBTreatments(); - IobTotal bolusIob = TreatmentsPlugin.getPlugin().getLastCalculationTreatments().round(); - TreatmentsPlugin.getPlugin().updateTotalIOBTempBasals(); - IobTotal basalIob = TreatmentsPlugin.getPlugin().getLastCalculationTempBasals().round(); - - bolusIobInsulin.setText(StringUtils.formatInsulin(-bolusIob.iob)); - basalIobInsulin.setText(StringUtils.formatInsulin(-basalIob.basaliob)); - - calculateInsulin(); - } - - private void calculateInsulin() { - ProfileStore profileStore = ConfigBuilderPlugin.getPlugin().getActiveProfileInterface().getProfile(); - if (profileSpinner == null || profileSpinner.getSelectedItem() == null || profileStore == null) - return; // not initialized yet - String profileName = profileSpinner.getSelectedItem().toString(); - Profile specificProfile; - if (profileName.equals(MainApp.gs(R.string.active))) { - specificProfile = ProfileFunctions.getInstance().getProfile(); - profileName = ProfileFunctions.getInstance().getProfileName(); - } else - specificProfile = profileStore.getSpecificProfile(profileName); - - // Entered values - Double c_bg = SafeParse.stringToDouble(editBg.getText()); - Integer c_carbs = SafeParse.stringToInt(editCarbs.getText()); - Double c_correction = SafeParse.stringToDouble(editCorr.getText()); - Double corrAfterConstraint = c_correction; - if (c_correction > 0) - c_correction = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(c_correction)).value(); - if (Math.abs(c_correction - corrAfterConstraint) > 0.01d) { // c_correction != corrAfterConstraint doesn't work - editCorr.setValue(0d); - ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.bolusconstraintapplied)); - return; - } - Integer carbsAfterConstraint = MainApp.getConstraintChecker().applyCarbsConstraints(new Constraint<>(c_carbs)).value(); - if (Math.abs(c_carbs - carbsAfterConstraint) > 0.01d) { - editCarbs.setValue(0d); - ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.carbsconstraintapplied)); - return; - } - - c_bg = bgCheckbox.isChecked() ? c_bg : 0d; - TempTarget tempTarget = ttCheckbox.isChecked() ? TreatmentsPlugin.getPlugin().getTempTargetFromHistory() : null; - - // COB - Double c_cob = 0d; - if (cobCheckbox.isChecked()) { - CobInfo cobInfo = IobCobCalculatorPlugin.getPlugin().getCobInfo(false, "Wizard COB"); - if (cobInfo.displayCob != null) - c_cob = cobInfo.displayCob; - } - - int carbTime = SafeParse.stringToInt(editCarbTime.getText()); - - wizard = new BolusWizard(specificProfile, profileName, tempTarget, carbsAfterConstraint, c_cob, c_bg, corrAfterConstraint, 100d, bgCheckbox.isChecked(), cobCheckbox.isChecked(), bolusIobCheckbox.isChecked(), basalIobCheckbox.isChecked(), superbolusCheckbox.isChecked(), ttCheckbox.isChecked(), bgtrendCheckbox.isChecked(), notesEdit.getText().toString(), carbTime); - - bg.setText(c_bg + " ISF: " + DecimalFormatter.to1Decimal(wizard.getSens())); - bgInsulin.setText(StringUtils.formatInsulin(wizard.getInsulinFromBG())); - - carbs.setText(DecimalFormatter.to0Decimal(c_carbs) + "g IC: " + DecimalFormatter.to1Decimal(wizard.getIc())); - carbsInsulin.setText(StringUtils.formatInsulin(wizard.getInsulinFromCarbs())); - - bolusIobInsulin.setText(StringUtils.formatInsulin(wizard.getInsulinFromBolusIOB())); - basalIobInsulin.setText(StringUtils.formatInsulin(wizard.getInsulinFromBasalsIOB())); - - correctionInsulin.setText(StringUtils.formatInsulin(wizard.getInsulinFromCorrection())); - - calculatedCarbs = carbsAfterConstraint; - - // Superbolus - superbolus.setText(superbolusCheckbox.isChecked() ? MainApp.gs(R.string.twohours) : ""); - superbolusInsulin.setText(StringUtils.formatInsulin(wizard.getInsulinFromSuperBolus())); - - // Trend - if (bgtrendCheckbox.isChecked() && wizard.getGlucoseStatus() != null) { - bgTrend.setText( - (wizard.getTrend() > 0 ? "+" : "") - + Profile.toUnitsString(wizard.getTrend() * 3, wizard.getTrend() * 3 / Constants.MMOLL_TO_MGDL, specificProfile.getUnits()) - + " " + specificProfile.getUnits()); - } else { - bgTrend.setText(""); - } - bgTrendInsulin.setText(StringUtils.formatInsulin(wizard.getInsulinFromTrend())); - - // COB - if (cobCheckbox.isChecked()) { - cob.setText(DecimalFormatter.to2Decimal(c_cob) + "g IC: " + DecimalFormatter.to1Decimal(wizard.getIc())); - cobInsulin.setText(StringUtils.formatInsulin(wizard.getInsulinFromCOB())); - } else { - cob.setText(""); - cobInsulin.setText(""); - } - - if (wizard.getCalculatedTotalInsulin() > 0d || calculatedCarbs > 0d) { - String insulinText = wizard.getCalculatedTotalInsulin() > 0d ? (DecimalFormatter.toPumpSupportedBolus(wizard.getCalculatedTotalInsulin()) + "U") : ""; - String carbsText = calculatedCarbs > 0d ? (DecimalFormatter.to0Decimal(calculatedCarbs) + "g") : ""; - total.setText(MainApp.gs(R.string.result) + ": " + insulinText + " " + carbsText); - okButton.setVisibility(View.VISIBLE); - } else { - // TODO this should also be run when loading the dialog as the OK button is initially visible - // but does nothing if neither carbs nor insulin is > 0 - total.setText(MainApp.gs(R.string.missing) + " " + DecimalFormatter.to0Decimal(wizard.getCarbsEquivalent()) + "g"); - okButton.setVisibility(View.INVISIBLE); - } - - } - -} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/dialogs/WizardDialog.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/dialogs/WizardDialog.kt new file mode 100644 index 0000000000..1b54b0c69c --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/dialogs/WizardDialog.kt @@ -0,0 +1,344 @@ +package info.nightscout.androidaps.plugins.general.overview.dialogs + +import android.content.Context +import android.os.Bundle +import android.text.Editable +import android.text.TextWatcher +import android.view.* +import android.widget.AdapterView +import android.widget.AdapterView.* +import android.widget.ArrayAdapter +import android.widget.CompoundButton +import androidx.fragment.app.DialogFragment +import info.nightscout.androidaps.Constants +import info.nightscout.androidaps.MainApp +import info.nightscout.androidaps.R +import info.nightscout.androidaps.data.Profile +import info.nightscout.androidaps.db.DatabaseHelper +import info.nightscout.androidaps.events.EventFeatureRunning +import info.nightscout.androidaps.interfaces.Constraint +import info.nightscout.androidaps.plugins.bus.RxBus +import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin +import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions +import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin +import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventAutosensCalculationFinished +import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin +import info.nightscout.androidaps.utils.* +import io.reactivex.android.schedulers.AndroidSchedulers +import io.reactivex.disposables.CompositeDisposable +import kotlinx.android.synthetic.main.okcancel.* +import kotlinx.android.synthetic.main.overview_wizard_dialog.* +import org.slf4j.LoggerFactory +import java.text.DecimalFormat +import java.util.* + +class WizardDialog : DialogFragment() { + private val log = LoggerFactory.getLogger(WizardDialog::class.java) + + private var wizard: BolusWizard? = null + private var parentContext: Context? = null + + //one shot guards + private var okClicked: Boolean = false + + private val textWatcher = object : TextWatcher { + override fun afterTextChanged(s: Editable) {} + + override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {} + + override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) { + calculateInsulin() + } + } + + private var disposable: CompositeDisposable = CompositeDisposable() + + override fun onAttach(context: Context?) { + super.onAttach(context) + this.parentContext = context + } + + override fun onDetach() { + super.onDetach() + this.parentContext = null + } + + override fun onResume() { + super.onResume() + MainApp.bus().post(EventFeatureRunning(EventFeatureRunning.Feature.WIZARD)) + } + + override fun onSaveInstanceState(savedInstanceState: Bundle) { + super.onSaveInstanceState(savedInstanceState) + savedInstanceState.putDouble("treatments_wizard_bginput", treatments_wizard_bginput.value) + savedInstanceState.putDouble("treatments_wizard_carbsinput", treatments_wizard_carbsinput.value) + savedInstanceState.putDouble("treatments_wizard_correctioninput", treatments_wizard_correctioninput.value) + savedInstanceState.putDouble("treatments_wizard_carbtimeinput", treatments_wizard_carbtimeinput.value) + } + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle?): View? { + dialog.window?.requestFeature(Window.FEATURE_NO_TITLE) + dialog.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN) + isCancelable = true + dialog.setCanceledOnTouchOutside(false) + + return inflater.inflate(R.layout.overview_wizard_dialog, container, false) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + loadCheckedStates() + processCobCheckBox() + treatments_wizard_sbcheckbox.visibility = if (SP.getBoolean(R.string.key_usesuperbolus, false)) View.VISIBLE else View.GONE + treatments_wizard_notes_layout.visibility = if (SP.getBoolean(R.string.key_show_notes_entry_dialogs, false)) View.VISIBLE else View.GONE + + val maxCarbs = MainApp.getConstraintChecker().maxCarbsAllowed.value() + val maxCorrection = MainApp.getConstraintChecker().maxBolusAllowed.value() + + treatments_wizard_bginput.setParams(savedInstanceState?.getDouble("treatments_wizard_bginput") + ?: 0.0, 0.0, 500.0, 0.1, DecimalFormat("0.0"), false, ok, textWatcher) + treatments_wizard_carbsinput.setParams(savedInstanceState?.getDouble("treatments_wizard_carbsinput") + ?: 0.0, 0.0, maxCarbs.toDouble(), 1.0, DecimalFormat("0"), false, ok, textWatcher) + val bolusstep = ConfigBuilderPlugin.getPlugin().activePump?.pumpDescription?.bolusStep + ?: 0.1 + treatments_wizard_correctioninput.setParams(savedInstanceState?.getDouble("treatments_wizard_correctioninput") + ?: 0.0, -maxCorrection, maxCorrection, bolusstep, DecimalFormatter.pumpSupportedBolusFormat(), false, ok, textWatcher) + treatments_wizard_carbtimeinput.setParams(savedInstanceState?.getDouble("treatments_wizard_carbtimeinput") + ?: 0.0, -60.0, 60.0, 5.0, DecimalFormat("0"), false, ok, textWatcher) + initDialog() + + // ok button + ok.setOnClickListener { + if (okClicked) { + log.debug("guarding: ok already clicked") + } else { + okClicked = true + parentContext?.let { context -> + wizard?.confirmAndExecute(context) + } + } + dismiss() + } + // cancel button + cancel.setOnClickListener { dismiss() } + // checkboxes + treatments_wizard_bgcheckbox.setOnCheckedChangeListener { buttonView, _ -> onCheckedChanged(buttonView) } + treatments_wizard_ttcheckbox.setOnCheckedChangeListener { buttonView, _ -> onCheckedChanged(buttonView) } + treatments_wizard_cobcheckbox.setOnCheckedChangeListener { buttonView, _ -> onCheckedChanged(buttonView) } + treatments_wizard_basaliobcheckbox.setOnCheckedChangeListener { buttonView, _ -> onCheckedChanged(buttonView) } + treatments_wizard_bolusiobcheckbox.setOnCheckedChangeListener { buttonView, _ -> onCheckedChanged(buttonView) } + treatments_wizard_bgtrendcheckbox.setOnCheckedChangeListener { buttonView, _ -> onCheckedChanged(buttonView) } + // profile spinner + treatments_wizard_profile.onItemSelectedListener = object : OnItemSelectedListener { + override fun onNothingSelected(parent: AdapterView<*>?) { + ToastUtils.showToastInUiThread(MainApp.instance().applicationContext, MainApp.gs(R.string.noprofileselected)) + ok.visibility = View.GONE + } + + override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) { + calculateInsulin() + ok.visibility = View.VISIBLE + } + } + // bus + disposable.add(RxBus + .toObservable(EventAutosensCalculationFinished::class.java) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe({ + activity?.runOnUiThread { calculateInsulin() } + }, { + FabricPrivacy.logException(it) + }) + ) + + } + + override fun onDestroyView() { + super.onDestroyView() + disposable.clear() + } + + fun onCheckedChanged(buttonView: CompoundButton) { + saveCheckedStates() + treatments_wizard_ttcheckbox.isEnabled = treatments_wizard_bgcheckbox.isChecked && TreatmentsPlugin.getPlugin().tempTargetFromHistory != null + if (buttonView.id == treatments_wizard_cobcheckbox.id) + processCobCheckBox() + calculateInsulin() + } + + private fun processCobCheckBox() { + if (treatments_wizard_cobcheckbox.isChecked) { + treatments_wizard_bolusiobcheckbox.isEnabled = false + treatments_wizard_basaliobcheckbox.isEnabled = false + treatments_wizard_bolusiobcheckbox.isChecked = true + treatments_wizard_basaliobcheckbox.isChecked = true + } else { + treatments_wizard_bolusiobcheckbox.isEnabled = true + treatments_wizard_basaliobcheckbox.isEnabled = true + } + } + + private fun saveCheckedStates() { + SP.putBoolean(MainApp.gs(R.string.key_wizard_include_cob), treatments_wizard_cobcheckbox.isChecked) + SP.putBoolean(MainApp.gs(R.string.key_wizard_include_trend_bg), treatments_wizard_bgtrendcheckbox.isChecked) + } + + private fun loadCheckedStates() { + treatments_wizard_bgtrendcheckbox.isChecked = SP.getBoolean(MainApp.gs(R.string.key_wizard_include_trend_bg), false) + treatments_wizard_cobcheckbox.isChecked = SP.getBoolean(MainApp.gs(R.string.key_wizard_include_cob), false) + } + + private fun initDialog() { + val profile = ProfileFunctions.getInstance().profile + val profileStore = ConfigBuilderPlugin.getPlugin().activeProfileInterface?.profile + + if (profile == null || profileStore == null) { + ToastUtils.showToastInUiThread(MainApp.instance().applicationContext, MainApp.gs(R.string.noprofile)) + dismiss() + return + } + + val profileList: ArrayList + profileList = profileStore.profileList + profileList.add(0, MainApp.gs(R.string.active)) + context?.let { context -> + val adapter = ArrayAdapter(context, R.layout.spinner_centered, profileList) + treatments_wizard_profile.adapter = adapter + } ?: return + + + val units = profile.units + treatments_wizard_bgunits.text = units + if (units == Constants.MGDL) + treatments_wizard_bginput.setStep(1.0) + else + treatments_wizard_bginput.setStep(0.1) + + // Set BG if not old + val lastBg = DatabaseHelper.actualBg() + + if (lastBg != null) { + treatments_wizard_bginput.value = lastBg.valueToUnits(units) + } else { + treatments_wizard_bginput.value = 0.0 + } + treatments_wizard_ttcheckbox.isEnabled = TreatmentsPlugin.getPlugin().tempTargetFromHistory != null + + // IOB calculation + TreatmentsPlugin.getPlugin().updateTotalIOBTreatments() + val bolusIob = TreatmentsPlugin.getPlugin().lastCalculationTreatments.round() + TreatmentsPlugin.getPlugin().updateTotalIOBTempBasals() + val basalIob = TreatmentsPlugin.getPlugin().lastCalculationTempBasals.round() + + treatments_wizard_bolusiobinsulin.text = StringUtils.formatInsulin(-bolusIob.iob) + treatments_wizard_basaliobinsulin.text = StringUtils.formatInsulin(-basalIob.basaliob) + + calculateInsulin() + + treatments_wizard_percent_used.visibility = if (SP.getInt(R.string.key_boluswizard_percentage, 100) != 100) View.VISIBLE else View.GONE + } + + private fun calculateInsulin() { + val profileStore = ConfigBuilderPlugin.getPlugin().activeProfileInterface?.profile + if (treatments_wizard_profile.selectedItem == null || profileStore == null) + return // not initialized yet + var profileName = treatments_wizard_profile.selectedItem.toString() + val specificProfile: Profile? + if (profileName == MainApp.gs(R.string.active)) { + specificProfile = ProfileFunctions.getInstance().profile + profileName = ProfileFunctions.getInstance().profileName + } else + specificProfile = profileStore.getSpecificProfile(profileName) + + if (specificProfile == null) return + + // Entered values + var c_bg = SafeParse.stringToDouble(treatments_wizard_bginput.text) + val c_carbs = SafeParse.stringToInt(treatments_wizard_carbsinput.text) + var c_correction = SafeParse.stringToDouble(treatments_wizard_correctioninput.text) + val corrAfterConstraint = c_correction + if (c_correction > 0) + c_correction = MainApp.getConstraintChecker().applyBolusConstraints(Constraint(c_correction)).value() + if (Math.abs(c_correction - corrAfterConstraint) > 0.01) { // c_correction != corrAfterConstraint doesn't work + treatments_wizard_correctioninput.value = 0.0 + ToastUtils.showToastInUiThread(MainApp.instance().applicationContext, MainApp.gs(R.string.bolusconstraintapplied)) + return + } + val carbsAfterConstraint = MainApp.getConstraintChecker().applyCarbsConstraints(Constraint(c_carbs)).value() + if (Math.abs(c_carbs - carbsAfterConstraint) > 0.01) { + treatments_wizard_carbsinput.value = 0.0 + ToastUtils.showToastInUiThread(MainApp.instance().applicationContext, MainApp.gs(R.string.carbsconstraintapplied)) + return + } + + c_bg = if (treatments_wizard_bgcheckbox.isChecked) c_bg else 0.0 + val tempTarget = if (treatments_wizard_ttcheckbox.isChecked) TreatmentsPlugin.getPlugin().tempTargetFromHistory else null + + // COB + var c_cob = 0.0 + if (treatments_wizard_cobcheckbox.isChecked) { + val cobInfo = IobCobCalculatorPlugin.getPlugin().getCobInfo(false, "Wizard COB") + cobInfo.displayCob?.let { c_cob = it } + } + + val carbTime = SafeParse.stringToInt(treatments_wizard_carbtimeinput.text) + + wizard = BolusWizard(specificProfile, profileName, tempTarget, carbsAfterConstraint, c_cob, c_bg, corrAfterConstraint, + SP.getInt(R.string.key_boluswizard_percentage, 100).toDouble(), + treatments_wizard_bgcheckbox.isChecked, + treatments_wizard_cobcheckbox.isChecked, + treatments_wizard_bolusiobcheckbox.isChecked, + treatments_wizard_basaliobcheckbox.isChecked, + treatments_wizard_sbcheckbox.isChecked, + treatments_wizard_ttcheckbox.isChecked, + treatments_wizard_bgtrendcheckbox.isChecked, + treatment_wizard_notes.text.toString(), carbTime) + + wizard?.let { wizard -> + treatments_wizard_bg.text = c_bg.toString() + " ISF: " + DecimalFormatter.to1Decimal(wizard.sens) + treatments_wizard_bginsulin.text = StringUtils.formatInsulin(wizard.insulinFromBG) + + treatments_wizard_carbs.text = DecimalFormatter.to0Decimal(c_carbs.toDouble()) + "g IC: " + DecimalFormatter.to1Decimal(wizard.ic) + treatments_wizard_carbsinsulin.text = StringUtils.formatInsulin(wizard.insulinFromCarbs) + + treatments_wizard_bolusiobinsulin.text = StringUtils.formatInsulin(wizard.insulinFromBolusIOB) + treatments_wizard_basaliobinsulin.text = StringUtils.formatInsulin(wizard.insulinFromBasalsIOB) + + treatments_wizard_correctioninsulin.text = StringUtils.formatInsulin(wizard.insulinFromCorrection) + + // Superbolus + treatments_wizard_sb.text = if (treatments_wizard_sbcheckbox.isChecked) MainApp.gs(R.string.twohours) else "" + treatments_wizard_sbinsulin.text = StringUtils.formatInsulin(wizard.insulinFromSuperBolus) + + // Trend + if (treatments_wizard_bgtrendcheckbox.isChecked && wizard.glucoseStatus != null) { + treatments_wizard_bgtrend.text = ((if (wizard.trend > 0) "+" else "") + + Profile.toUnitsString(wizard.trend * 3, wizard.trend * 3 / Constants.MMOLL_TO_MGDL, specificProfile.units) + + " " + specificProfile.units) + } else { + treatments_wizard_bgtrend.text = "" + } + treatments_wizard_bgtrendinsulin.text = StringUtils.formatInsulin(wizard.insulinFromTrend) + + // COB + if (treatments_wizard_cobcheckbox.isChecked) { + treatments_wizard_cob.text = DecimalFormatter.to2Decimal(c_cob) + "g IC: " + DecimalFormatter.to1Decimal(wizard.ic) + treatments_wizard_cobinsulin.text = StringUtils.formatInsulin(wizard.insulinFromCOB) + } else { + treatments_wizard_cob.text = "" + treatments_wizard_cobinsulin.text = "" + } + + if (wizard.calculatedTotalInsulin > 0.0 || carbsAfterConstraint > 0.0) { + val insulinText = if (wizard.calculatedTotalInsulin > 0.0) DecimalFormatter.toPumpSupportedBolus(wizard.calculatedTotalInsulin) + "U" else "" + val carbsText = if (carbsAfterConstraint > 0.0) DecimalFormatter.to0Decimal(carbsAfterConstraint.toDouble()) + "g" else "" + treatments_wizard_total.text = MainApp.gs(R.string.result) + ": " + insulinText + " " + carbsText + ok.visibility = View.VISIBLE + } else { + treatments_wizard_total.text = MainApp.gs(R.string.missing) + " " + DecimalFormatter.to0Decimal(wizard.carbsEquivalent) + "g" + ok.visibility = View.INVISIBLE + } + } + + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/IobCobThread.java b/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/IobCobThread.java index 943637fd4e..4694685ea6 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/IobCobThread.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/IobCobThread.java @@ -22,6 +22,7 @@ import info.nightscout.androidaps.events.Event; import info.nightscout.androidaps.interfaces.PluginType; import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.aps.openAPSSMB.SMBDefaults; +import info.nightscout.androidaps.plugins.bus.RxBus; import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification; @@ -312,6 +313,7 @@ public class IobCobThread extends Thread { new Thread(() -> { SystemClock.sleep(1000); MainApp.bus().post(new EventAutosensCalculationFinished(cause)); + RxBus.INSTANCE.send(new EventAutosensCalculationFinished(cause)); }).start(); } finally { if (mWakeLock != null) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/events/EventAutosensCalculationFinished.java b/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/events/EventAutosensCalculationFinished.java deleted file mode 100644 index 25622843e7..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/events/EventAutosensCalculationFinished.java +++ /dev/null @@ -1,16 +0,0 @@ -package info.nightscout.androidaps.plugins.iob.iobCobCalculator.events; - -import info.nightscout.androidaps.events.Event; -import info.nightscout.androidaps.events.EventLoop; - -/** - * Created by mike on 30.04.2017. - */ - -public class EventAutosensCalculationFinished extends EventLoop { - public Event cause; - - public EventAutosensCalculationFinished(Event cause) { - this.cause = cause; - } -} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/events/EventAutosensCalculationFinished.kt b/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/events/EventAutosensCalculationFinished.kt new file mode 100644 index 0000000000..aa96aaf0b0 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/events/EventAutosensCalculationFinished.kt @@ -0,0 +1,6 @@ +package info.nightscout.androidaps.plugins.iob.iobCobCalculator.events + +import info.nightscout.androidaps.events.Event +import info.nightscout.androidaps.events.EventLoop + +class EventAutosensCalculationFinished(var cause: Event) : EventLoop() diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/treatments/dialogs/WizardInfoDialog.java b/app/src/main/java/info/nightscout/androidaps/plugins/treatments/dialogs/WizardInfoDialog.java deleted file mode 100644 index e068e094f1..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/treatments/dialogs/WizardInfoDialog.java +++ /dev/null @@ -1,86 +0,0 @@ -package info.nightscout.androidaps.plugins.treatments.dialogs; - -import android.os.Bundle; -import androidx.fragment.app.DialogFragment; -import android.view.LayoutInflater; -import android.view.View; -import android.view.View.OnClickListener; -import android.view.ViewGroup; -import android.view.WindowManager; -import android.widget.CheckBox; -import android.widget.TextView; - -import org.json.JSONObject; - -import info.nightscout.androidaps.R; -import info.nightscout.androidaps.utils.DecimalFormatter; -import info.nightscout.androidaps.utils.JsonHelper; - -public class WizardInfoDialog extends DialogFragment implements OnClickListener { - JSONObject json; - - public WizardInfoDialog() { - super(); - } - - public void setData(JSONObject json) { - this.json = json; - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - View view = inflater.inflate(R.layout.treatments_wizardinfo_dialog, container, false); - - getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN); - - view.findViewById(R.id.ok).setOnClickListener(this); - - // BG - ((TextView) view.findViewById(R.id.treatments_wizard_bg)).setText(DecimalFormatter.to1Decimal(JsonHelper.safeGetDouble(json, "bg")) + " ISF: " + DecimalFormatter.to1Decimal(JsonHelper.safeGetDouble(json, "isf"))); - ((TextView) view.findViewById(R.id.treatments_wizard_bginsulin)).setText(DecimalFormatter.to2Decimal(JsonHelper.safeGetDouble(json, "insulinbg")) + "U"); - ((CheckBox) view.findViewById(R.id.treatments_wizard_bgcheckbox)).setChecked(JsonHelper.safeGetBoolean(json, "insulinbgused")); - ((CheckBox) view.findViewById(R.id.treatments_wizard_ttcheckbox)).setChecked(JsonHelper.safeGetBoolean(json, "ttused")); - // Trend - ((TextView) view.findViewById(R.id.treatments_wizard_bgtrend)).setText(JsonHelper.safeGetString(json, "trend")); - ((TextView) view.findViewById(R.id.treatments_wizard_bgtrendinsulin)).setText(DecimalFormatter.to2Decimal(JsonHelper.safeGetDouble(json, "insulintrend")) + "U"); - ((CheckBox) view.findViewById(R.id.treatments_wizard_bgtrendcheckbox)).setChecked(JsonHelper.safeGetBoolean(json, "trendused")); - // COB - ((TextView) view.findViewById(R.id.treatments_wizard_cob)).setText(DecimalFormatter.to0Decimal(JsonHelper.safeGetDouble(json, "cob")) + "g IC: " + DecimalFormatter.to1Decimal(JsonHelper.safeGetDouble(json, "ic"))); - ((TextView) view.findViewById(R.id.treatments_wizard_cobinsulin)).setText(DecimalFormatter.to2Decimal(JsonHelper.safeGetDouble(json, "insulincob")) + "U"); - ((CheckBox) view.findViewById(R.id.treatments_wizard_cobcheckbox)).setChecked(JsonHelper.safeGetBoolean(json, "cobused")); - // Bolus IOB - ((TextView) view.findViewById(R.id.treatments_wizard_bolusiobinsulin)).setText(DecimalFormatter.to2Decimal(JsonHelper.safeGetDouble(json, "bolusiob")) + "U"); - ((CheckBox) view.findViewById(R.id.treatments_wizard_bolusiobcheckbox)).setChecked(JsonHelper.safeGetBoolean(json, "bolusiobused")); - // Basal IOB - ((TextView) view.findViewById(R.id.treatments_wizard_basaliobinsulin)).setText(DecimalFormatter.to2Decimal(JsonHelper.safeGetDouble(json, "basaliob")) + "U"); - ((CheckBox) view.findViewById(R.id.treatments_wizard_basaliobcheckbox)).setChecked(JsonHelper.safeGetBoolean(json, "basaliobused")); - // Superbolus - ((TextView) view.findViewById(R.id.treatments_wizard_sbinsulin)).setText(DecimalFormatter.to2Decimal(JsonHelper.safeGetDouble(json, "insulinsuperbolus")) + "U"); - ((CheckBox) view.findViewById(R.id.treatments_wizard_sbcheckbox)).setChecked(JsonHelper.safeGetBoolean(json, "superbolusused")); - // Carbs - ((TextView) view.findViewById(R.id.treatments_wizard_carbs)).setText(DecimalFormatter.to0Decimal(JsonHelper.safeGetDouble(json, "carbs")) + "g IC: " + DecimalFormatter.to1Decimal(JsonHelper.safeGetDouble(json, "ic"))); - ((TextView) view.findViewById(R.id.treatments_wizard_carbsinsulin)).setText(DecimalFormatter.to2Decimal(JsonHelper.safeGetDouble(json, "insulincarbs")) + "U"); - // Correction - ((TextView) view.findViewById(R.id.treatments_wizard_correctioninsulin)).setText(DecimalFormatter.to2Decimal(JsonHelper.safeGetDouble(json, "othercorrection")) + "U"); - // Profile - ((TextView) view.findViewById(R.id.treatments_wizard_profile)).setText(JsonHelper.safeGetString(json, "profile")); - // Notes - ((TextView) view.findViewById(R.id.treatments_wizard_notes)).setText(JsonHelper.safeGetString(json, "notes")); - // Total - ((TextView) view.findViewById(R.id.treatments_wizard_totalinsulin)).setText(DecimalFormatter.to2Decimal(JsonHelper.safeGetDouble(json, "insulin")) + "U"); - - setCancelable(true); - return view; - } - - @Override - public synchronized void onClick(View view) { - switch (view.getId()) { - case R.id.ok: - dismiss(); - break; - } - } - -} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/treatments/dialogs/WizardInfoDialog.kt b/app/src/main/java/info/nightscout/androidaps/plugins/treatments/dialogs/WizardInfoDialog.kt new file mode 100644 index 0000000000..4e77a8f758 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/treatments/dialogs/WizardInfoDialog.kt @@ -0,0 +1,70 @@ +package info.nightscout.androidaps.plugins.treatments.dialogs + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.view.WindowManager +import androidx.fragment.app.DialogFragment +import info.nightscout.androidaps.R +import info.nightscout.androidaps.utils.DecimalFormatter +import info.nightscout.androidaps.utils.JsonHelper +import kotlinx.android.synthetic.main.treatments_wizardinfo_dialog.* +import org.json.JSONObject + +class WizardInfoDialog : DialogFragment() { + private var json: JSONObject? = null + + fun setData(json: JSONObject) { + this.json = json + } + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle?): View? { + dialog.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN) + isCancelable = true + return inflater.inflate(R.layout.treatments_wizardinfo_dialog, container, false) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + close.setOnClickListener { dismiss() } + + // BG + treatments_wizard_bg.text = DecimalFormatter.to1Decimal(JsonHelper.safeGetDouble(json, "bg")) + " ISF: " + DecimalFormatter.to1Decimal(JsonHelper.safeGetDouble(json, "isf")) + treatments_wizard_bginsulin.text = DecimalFormatter.to2Decimal(JsonHelper.safeGetDouble(json, "insulinbg")) + "U" + treatments_wizard_bgcheckbox.isChecked = JsonHelper.safeGetBoolean(json, "insulinbgused") + treatments_wizard_ttcheckbox.isChecked = JsonHelper.safeGetBoolean(json, "ttused") + // Trend + treatments_wizard_bgtrend.text = JsonHelper.safeGetString(json, "trend") + treatments_wizard_bgtrendinsulin.text = DecimalFormatter.to2Decimal(JsonHelper.safeGetDouble(json, "insulintrend")) + "U" + treatments_wizard_bgtrendcheckbox.isChecked = JsonHelper.safeGetBoolean(json, "trendused") + // COB + treatments_wizard_cob.text = DecimalFormatter.to0Decimal(JsonHelper.safeGetDouble(json, "cob")) + "g IC: " + DecimalFormatter.to1Decimal(JsonHelper.safeGetDouble(json, "ic")) + treatments_wizard_cobinsulin.text = DecimalFormatter.to2Decimal(JsonHelper.safeGetDouble(json, "insulincob")) + "U" + treatments_wizard_cobcheckbox.isChecked = JsonHelper.safeGetBoolean(json, "cobused") + // Bolus IOB + treatments_wizard_bolusiobinsulin.text = DecimalFormatter.to2Decimal(JsonHelper.safeGetDouble(json, "bolusiob")) + "U" + treatments_wizard_bolusiobcheckbox.isChecked = JsonHelper.safeGetBoolean(json, "bolusiobused") + // Basal IOB + treatments_wizard_basaliobinsulin.text = DecimalFormatter.to2Decimal(JsonHelper.safeGetDouble(json, "basaliob")) + "U" + treatments_wizard_basaliobcheckbox.isChecked = JsonHelper.safeGetBoolean(json, "basaliobused") + // Superbolus + treatments_wizard_sbinsulin.text = DecimalFormatter.to2Decimal(JsonHelper.safeGetDouble(json, "insulinsuperbolus")) + "U" + treatments_wizard_sbcheckbox.isChecked = JsonHelper.safeGetBoolean(json, "superbolusused") + // Carbs + treatments_wizard_carbs.text = DecimalFormatter.to0Decimal(JsonHelper.safeGetDouble(json, "carbs")) + "g IC: " + DecimalFormatter.to1Decimal(JsonHelper.safeGetDouble(json, "ic")) + treatments_wizard_carbsinsulin.text = DecimalFormatter.to2Decimal(JsonHelper.safeGetDouble(json, "insulincarbs")) + "U" + // Correction + treatments_wizard_correctioninsulin.text = DecimalFormatter.to2Decimal(JsonHelper.safeGetDouble(json, "othercorrection")) + "U" + // Profile + treatments_wizard_profile.text = JsonHelper.safeGetString(json, "profile") + // Notes + treatments_wizard_notes.text = JsonHelper.safeGetString(json, "notes") + // Percentage + treatments_wizard_percent_used.text = DecimalFormatter.to0Decimal(JsonHelper.safeGetDouble(json, "percentageCorrection", 100.0)) + "%" + // Total + treatments_wizard_totalinsulin.text = DecimalFormatter.to2Decimal(JsonHelper.safeGetDouble(json, "insulin")) + "U" + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/utils/BolusWizard.kt b/app/src/main/java/info/nightscout/androidaps/utils/BolusWizard.kt index b741e4656c..598616f1bf 100644 --- a/app/src/main/java/info/nightscout/androidaps/utils/BolusWizard.kt +++ b/app/src/main/java/info/nightscout/androidaps/utils/BolusWizard.kt @@ -231,6 +231,7 @@ class BolusWizard @JvmOverloads constructor(val profile: Profile, boluscalcJSON.put("insulintrend", insulinFromTrend) boluscalcJSON.put("trend", trend) boluscalcJSON.put("ttused", useTT) + boluscalcJSON.put("percentageCorrection", percentageCorrection) } catch (e: JSONException) { log.error("Unhandled exception", e) } diff --git a/app/src/main/java/info/nightscout/androidaps/utils/JsonHelper.java b/app/src/main/java/info/nightscout/androidaps/utils/JsonHelper.java index 8f715a0448..5308c62420 100644 --- a/app/src/main/java/info/nightscout/androidaps/utils/JsonHelper.java +++ b/app/src/main/java/info/nightscout/androidaps/utils/JsonHelper.java @@ -72,6 +72,19 @@ public class JsonHelper { return result; } + public static double safeGetDouble(JSONObject json, String fieldName, double defaultValue) { + double result = defaultValue; + + if (json != null && json.has(fieldName)) { + try { + result = json.getDouble(fieldName); + } catch (JSONException ignored) { + } + } + + return result; + } + public static int safeGetInt(JSONObject json, String fieldName) { int result = 0; diff --git a/app/src/main/res/layout/overview_wizard_dialog.xml b/app/src/main/res/layout/overview_wizard_dialog.xml index 7fc3c32f3a..a6a278a89d 100644 --- a/app/src/main/res/layout/overview_wizard_dialog.xml +++ b/app/src/main/res/layout/overview_wizard_dialog.xml @@ -197,6 +197,18 @@ android:text="2.35U 28g" android:textAppearance="?android:attr/textAppearanceLarge" /> + + - + + + + + + + + + + + +