TempTargetDialog

This commit is contained in:
Milos Kozak 2019-12-18 23:22:03 +01:00
parent 8d874e14d3
commit f7716c79fe
10 changed files with 325 additions and 72 deletions

View file

@ -21,9 +21,8 @@ import info.nightscout.androidaps.plugins.general.actions.defs.CustomAction
import info.nightscout.androidaps.plugins.general.actions.dialogs.FillDialog
import info.nightscout.androidaps.plugins.general.actions.dialogs.NewExtendedBolusDialog
import info.nightscout.androidaps.plugins.general.actions.dialogs.NewTempBasalDialog
import info.nightscout.androidaps.plugins.general.careportal.CareportalFragment
import info.nightscout.androidaps.plugins.general.careportal.Dialogs.NewNSTreatmentDialog
import info.nightscout.androidaps.plugins.general.overview.dialogs.ProfileSwitchDialog
import info.nightscout.androidaps.plugins.general.overview.dialogs.TempTargetDialog
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
import info.nightscout.androidaps.queue.Callback
import info.nightscout.androidaps.utils.*
@ -51,11 +50,7 @@ class ActionsFragment : Fragment() {
fragmentManager?.let { ProfileSwitchDialog().show(it, "Actions") }
}
actions_temptarget.setOnClickListener {
val newTTDialog = NewNSTreatmentDialog()
val temptarget = CareportalFragment.TEMPTARGET
temptarget.executeTempTarget = true
newTTDialog.setOptions(temptarget, R.string.careportal_temporarytarget)
fragmentManager?.let { newTTDialog.show(it, "NewNSTreatmentDialog") }
fragmentManager?.let { TempTargetDialog().show(it, "Actions") }
}
actions_extendedbolus.setOnClickListener {
fragmentManager?.let { NewExtendedBolusDialog().show(it, "NewExtendedDialog") }

View file

@ -200,7 +200,6 @@ public class CareportalFragment extends Fragment implements View.OnClickListener
newDialog.setOptions(OPENAPSOFFLINE, R.string.careportal_openapsoffline);
break;
case R.id.careportal_temporarytarget:
TEMPTARGET.executeTempTarget = false;
newDialog.setOptions(TEMPTARGET, R.string.careportal_temporarytarget);
break;
default:
@ -220,7 +219,7 @@ public class CareportalFragment extends Fragment implements View.OnClickListener
activity.runOnUiThread(
() -> {
CareportalEvent careportalEvent;
NSSettingsStatus nsSettings = new NSSettingsStatus().getInstance();
NSSettingsStatus nsSettings = NSSettingsStatus.getInstance();
double iageUrgent = nsSettings.getExtendedWarnValue("iage", "urgent", 96);
double iageWarn = nsSettings.getExtendedWarnValue("iage", "warn", 72);

View file

@ -45,8 +45,6 @@ import info.nightscout.androidaps.data.ProfileStore;
import info.nightscout.androidaps.db.BgReading;
import info.nightscout.androidaps.db.CareportalEvent;
import info.nightscout.androidaps.db.ProfileSwitch;
import info.nightscout.androidaps.db.Source;
import info.nightscout.androidaps.db.TempTarget;
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
import info.nightscout.androidaps.plugins.general.careportal.OptionsToShow;
@ -68,7 +66,7 @@ public class NewNSTreatmentDialog extends AppCompatDialogFragment implements Vie
private static OptionsToShow options;
private static String event;
Profile profile;
private Profile profile;
public ProfileStore profileStore;
TextView eventTypeText;
@ -703,41 +701,18 @@ public class NewNSTreatmentDialog extends AppCompatDialogFragment implements Vie
void createNSTreatment(JSONObject data) {
if (options.executeTempTarget) {
final int duration = JsonHelper.safeGetInt(data, "duration");
final double targetBottom = JsonHelper.safeGetDouble(data, "targetBottom");
final double targetTop = JsonHelper.safeGetDouble(data, "targetTop");
final String reason = JsonHelper.safeGetString(data, "reason", "");
if ((targetBottom != 0d && targetTop != 0d) || duration == 0) {
TempTarget tempTarget = new TempTarget()
.date(eventTime.getTime())
.duration(duration)
.reason(reason)
.source(Source.USER);
if (tempTarget.durationInMinutes != 0) {
tempTarget.low(Profile.toMgdl(targetBottom, ProfileFunctions.getSystemUnits()))
.high(Profile.toMgdl(targetTop, ProfileFunctions.getSystemUnits()));
} else {
tempTarget.low(0).high(0);
}
TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget);
}
if (duration == 10)
SP.putBoolean(R.string.key_objectiveusetemptarget, true);
if (JsonHelper.safeGetString(data, "eventType").equals(CareportalEvent.PROFILESWITCH)) {
ProfileSwitch profileSwitch = ProfileFunctions.prepareProfileSwitch(
profileStore,
JsonHelper.safeGetString(data, "profile"),
JsonHelper.safeGetInt(data, "duration"),
JsonHelper.safeGetInt(data, "percentage"),
JsonHelper.safeGetInt(data, "timeshift"),
eventTime.getTime()
);
NSUpload.uploadProfileSwitch(profileSwitch);
} else {
if (JsonHelper.safeGetString(data, "eventType").equals(CareportalEvent.PROFILESWITCH)) {
ProfileSwitch profileSwitch = ProfileFunctions.prepareProfileSwitch(
profileStore,
JsonHelper.safeGetString(data, "profile"),
JsonHelper.safeGetInt(data, "duration"),
JsonHelper.safeGetInt(data, "percentage"),
JsonHelper.safeGetInt(data, "timeshift"),
eventTime.getTime()
);
NSUpload.uploadProfileSwitch(profileSwitch);
} else {
NSUpload.uploadCareportalEntryToNS(data);
}
NSUpload.uploadCareportalEntryToNS(data);
}
}

View file

@ -19,9 +19,6 @@ public class OptionsToShow {
public boolean split;
public boolean tempTarget;
// perform direct actions
public boolean executeTempTarget = false;
public OptionsToShow(int eventType, int eventName) {
this.eventType = eventType;
this.eventName = eventName;

View file

@ -94,6 +94,7 @@ import info.nightscout.androidaps.plugins.general.overview.dialogs.NewCarbsDialo
import info.nightscout.androidaps.plugins.general.overview.dialogs.NewInsulinDialog;
import info.nightscout.androidaps.plugins.general.overview.dialogs.NewTreatmentDialog;
import info.nightscout.androidaps.plugins.general.overview.dialogs.ProfileSwitchDialog;
import info.nightscout.androidaps.plugins.general.overview.dialogs.TempTargetDialog;
import info.nightscout.androidaps.plugins.general.overview.dialogs.WizardDialog;
import info.nightscout.androidaps.plugins.general.overview.graphData.GraphData;
import info.nightscout.androidaps.plugins.general.wear.ActionStringHandler;
@ -791,11 +792,9 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
.high(target);
TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget);
} else if (item.getTitle().equals(MainApp.gs(R.string.custom))) {
NewNSTreatmentDialog newTTDialog = new NewNSTreatmentDialog();
final OptionsToShow temptarget = CareportalFragment.TEMPTARGET;
temptarget.executeTempTarget = true;
newTTDialog.setOptions(temptarget, R.string.careportal_temporarytarget);
newTTDialog.show(getFragmentManager(), "NewNSTreatmentDialog");
FragmentManager manager = getFragmentManager();
if (manager != null)
new TempTargetDialog().show(manager, "Overview");
} else if (item.getTitle().equals(MainApp.gs(R.string.cancel))) {
TempTarget tempTarget = new TempTarget()
.source(Source.USER)
@ -817,7 +816,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
FragmentManager manager = getFragmentManager();
// try to fix https://fabric.io/nightscout3/android/apps/info.nightscout.androidaps/issues/5aca7a1536c7b23527eb4be7?time=last-seven-days
// https://stackoverflow.com/questions/14860239/checking-if-state-is-saved-before-committing-a-fragmenttransaction
if (manager.isStateSaved())
if (manager == null || manager.isStateSaved())
return;
switch (v.getId()) {
case R.id.overview_accepttempbutton:

View file

@ -1,7 +1,9 @@
package info.nightscout.androidaps.plugins.general.overview.dialogs
import android.os.Bundle
import android.view.*
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ArrayAdapter
import com.google.common.base.Joiner
import info.nightscout.androidaps.Constants
@ -9,18 +11,18 @@ import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.HtmlHelper
import info.nightscout.androidaps.utils.OKDialog
import kotlinx.android.synthetic.main.okcancel.*
import kotlinx.android.synthetic.main.overview_profileswitch_dialog.*
import org.slf4j.LoggerFactory
import java.text.DecimalFormat
import java.util.*
class ProfileSwitchDialog : DialogFragmentWithDate() {
override fun onSaveInstanceState(savedInstanceState: Bundle) {
override fun onSaveInstanceState(savedInstanceState: Bundle) {
super.onSaveInstanceState(savedInstanceState)
savedInstanceState.putDouble("overview_profileswitch_duration", overview_profileswitch_duration.value)
savedInstanceState.putDouble("overview_profileswitch_percentage", overview_profileswitch_percentage.value)
@ -55,6 +57,19 @@ class ProfileSwitchDialog : DialogFragmentWithDate() {
if (profileList[p] == ProfileFunctions.getInstance().getProfileName(false))
overview_profileswitch_profile.setSelection(p)
} ?: return
TreatmentsPlugin.getPlugin().getProfileSwitchFromHistory(DateUtil.now())?.let { ps ->
if (ps.isCPP) {
overview_profileswitch_reuselayout.visibility = View.VISIBLE
overview_profileswitch_reusebutton.text = MainApp.gs(R.string.reuse) + " " + ps.percentage + "% " + ps.timeshift + "h"
overview_profileswitch_reusebutton.setOnClickListener {
overview_profileswitch_percentage.value = ps.percentage.toDouble()
overview_profileswitch_timeshift.value = ps.timeshift.toDouble()
}
} else {
overview_profileswitch_reuselayout.visibility = View.GONE
}
}
}
override fun submit() {
@ -65,7 +80,7 @@ class ProfileSwitchDialog : DialogFragmentWithDate() {
if (duration > 0)
actions.add(MainApp.gs(R.string.duration) + ": " + MainApp.gs(R.string.format_hours, duration))
val profile = overview_profileswitch_profile.selectedItem.toString()
actions.add(MainApp.gs(R.string.profile).toString() + ": " + profile)
actions.add(MainApp.gs(R.string.profile) + ": " + profile)
val percent = overview_profileswitch_percentage.value.toInt()
if (percent != 100)
actions.add(MainApp.gs(R.string.percent) + ": " + percent + "%")

View file

@ -0,0 +1,142 @@
package info.nightscout.androidaps.plugins.general.overview.dialogs
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.AdapterView
import android.widget.ArrayAdapter
import com.google.common.base.Joiner
import com.google.common.collect.Lists
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.Source
import info.nightscout.androidaps.db.TempTarget
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
import info.nightscout.androidaps.utils.*
import kotlinx.android.synthetic.main.okcancel.*
import kotlinx.android.synthetic.main.overview_temptarget_dialog.*
import java.text.DecimalFormat
import java.util.*
class TempTargetDialog : DialogFragmentWithDate() {
override fun onSaveInstanceState(savedInstanceState: Bundle) {
super.onSaveInstanceState(savedInstanceState)
savedInstanceState.putDouble("overview_temptarget_duration", overview_temptarget_duration.value)
savedInstanceState.putDouble("overview_temptarget_temptarget", overview_temptarget_temptarget.value)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
onCreateView()
return inflater.inflate(R.layout.overview_temptarget_dialog, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
overview_temptarget_duration.setParams(savedInstanceState?.getDouble("overview_temptarget_duration")
?: 0.0, 0.0, Constants.MAX_PROFILE_SWITCH_DURATION, 10.0, DecimalFormat("0"), false, ok)
if (ProfileFunctions.getSystemUnits() == Constants.MMOL)
overview_temptarget_temptarget.setParams(
savedInstanceState?.getDouble("overview_temptarget_temptarget")
?: Constants.MIN_TT_MMOL,
Constants.MIN_TT_MMOL, Constants.MAX_TT_MMOL, 0.1, DecimalFormat("0.0"), false, ok)
else
overview_temptarget_temptarget.setParams(
savedInstanceState?.getDouble("overview_temptarget_temptarget")
?: Constants.MIN_TT_MGDL,
Constants.MIN_TT_MGDL, Constants.MAX_TT_MGDL, 1.0, DecimalFormat("0"), false, ok)
// temp target
context?.let { context ->
val reasonList: List<String> = Lists.newArrayList(
MainApp.gs(R.string.manual),
MainApp.gs(R.string.cancel),
MainApp.gs(R.string.eatingsoon),
MainApp.gs(R.string.activity),
MainApp.gs(R.string.hypo)
)
val adapterReason = ArrayAdapter(context, R.layout.spinner_centered, reasonList)
overview_temptarget_reason.adapter = adapterReason
overview_temptarget_reason.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(parent: AdapterView<*>?, view: View, position: Int, id: Long) {
val defaultDuration: Double
val defaultTarget: Double
val helper = DefaultValueHelper()
when (reasonList[position]) {
MainApp.gs(R.string.eatingsoon) -> {
defaultDuration = helper.determineEatingSoonTTDuration().toDouble()
defaultTarget = helper.determineEatingSoonTT()
}
MainApp.gs(R.string.activity) -> {
defaultDuration = helper.determineActivityTTDuration().toDouble()
defaultTarget = helper.determineActivityTT()
}
MainApp.gs(R.string.hypo) -> {
defaultDuration = helper.determineHypoTTDuration().toDouble()
defaultTarget = helper.determineHypoTT()
}
MainApp.gs(R.string.cancel) -> {
defaultDuration = 0.0
defaultTarget = 0.0
}
else -> {
defaultDuration = overview_temptarget_duration.value
defaultTarget = overview_temptarget_temptarget.value
}
}
overview_temptarget_temptarget.value = defaultTarget
overview_temptarget_duration.value = defaultDuration
}
override fun onNothingSelected(parent: AdapterView<*>?) {}
}
}
}
override fun submit() {
val actions: LinkedList<String> = LinkedList()
val reason = overview_temptarget_reason.selectedItem.toString()
val unitResId = if (ProfileFunctions.getSystemUnits() == Constants.MGDL) R.string.mgdl else R.string.mmol
val target = overview_temptarget_temptarget.value
val duration = overview_temptarget_duration.value
if (target != 0.0 && duration != 0.0) {
actions.add(MainApp.gs(R.string.reason) + ": " + reason)
actions.add(MainApp.gs(R.string.nsprofileview_target_label) + ": " + Profile.toCurrentUnitsString(target) + " " + MainApp.gs(unitResId))
actions.add(MainApp.gs(R.string.duration) + ": " + MainApp.gs(R.string.format_hours, duration))
} else {
actions.add(MainApp.gs(R.string.stoptemptarget))
}
if (eventTimeChanged)
actions.add(MainApp.gs(R.string.time) + ": " + DateUtil.dateAndTimeString(eventTime))
activity?.let { activity ->
OKDialog.showConfirmation(activity, HtmlHelper.fromHtml(Joiner.on("<br/>").join(actions))) {
if (target == 0.0 || duration == 0.0) {
val tempTarget = TempTarget()
.date(eventTime)
.duration(0)
.low(0.0).high(0.0)
.source(Source.USER)
TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget)
} else {
val tempTarget = TempTarget()
.date(eventTime)
.duration(duration.toInt())
.reason(reason)
.source(Source.USER)
.low(Profile.toMgdl(target, ProfileFunctions.getSystemUnits()))
.high(Profile.toMgdl(target, ProfileFunctions.getSystemUnits()))
TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget)
}
if (duration == 10.0) SP.putBoolean(R.string.key_objectiveusetemptarget, true)
}
}
}
}

View file

@ -35,7 +35,7 @@ class WizardInfoDialog : DialogFragment() {
close.setOnClickListener { dismiss() }
val units = ProfileFunctions.getSystemUnits()
var bg_string= ""
val bg_string: String
if (units.equals(Constants.MGDL)) { bg_string = DecimalFormatter.to0Decimal(JsonHelper.safeGetDouble(json, "bg"))} else { bg_string = DecimalFormatter.to1Decimal(JsonHelper.safeGetDouble(json, "bg"))}
// BG
treatments_wizard_bg.text = MainApp.gs(R.string.format_bg_isf, bg_string , JsonHelper.safeGetDouble(json, "isf"))

View file

@ -22,7 +22,8 @@
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/icon_actions_profileswitch" />
android:src="@drawable/icon_actions_profileswitch"
android:contentDescription="@string/careportal_profileswitch" />
<TextView
android:layout_width="match_parent"
@ -60,10 +61,11 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:gravity="left"
android:gravity="start"
android:minWidth="45dp"
android:paddingLeft="5dp"
android:text="min"
android:paddingStart="5dp"
android:paddingEnd="5dp"
android:text="@string/unit_minute_short"
android:textAppearance="?android:attr/textAppearanceSmall" />
</LinearLayout>
@ -87,12 +89,12 @@
android:id="@+id/overview_profileswitch_profile"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_gravity="center_vertical" />
</LinearLayout>
<LinearLayout
android:id="@+id/overview_profileswitch_reuselayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
@ -118,9 +120,10 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:gravity="left"
android:gravity="start"
android:minWidth="45dp"
android:paddingLeft="5dp"
android:paddingStart="5dp"
android:paddingEnd="5dp"
android:text=" "
android:textAppearance="?android:attr/textAppearanceSmall" />
@ -150,9 +153,10 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:gravity="left"
android:gravity="start"
android:minWidth="45dp"
android:paddingLeft="5dp"
android:paddingStart="5dp"
android:paddingEnd="5dp"
android:text="%"
android:textAppearance="?android:attr/textAppearanceSmall" />
@ -182,10 +186,11 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:gravity="left"
android:gravity="start"
android:minWidth="45dp"
android:paddingLeft="5dp"
android:text="h"
android:paddingStart="5dp"
android:paddingEnd="5dp"
android:text="@string/unit_hours"
android:textAppearance="?android:attr/textAppearanceSmall" />
</LinearLayout>

View file

@ -0,0 +1,126 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusableInTouchMode="true"
android:minWidth="300dp"
android:orientation="vertical"
android:padding="10dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:orientation="horizontal"
android:padding="10dp">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/icon_actions_temptarget"
android:contentDescription="@string/careportal_temporarytarget" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:text="@string/careportal_temporarytarget"
android:textAlignment="center"
android:textAppearance="?android:attr/textAppearanceLarge" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/reason"
android:width="120dp"
android:padding="10dp"
android:textAppearance="@android:style/TextAppearance.Material.Small"
android:layout_gravity="center_vertical"
android:textStyle="bold" />
<Spinner
android:id="@+id/overview_temptarget_reason"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/nsprofileview_target_label"
android:width="120dp"
android:padding="10dp"
android:textAppearance="@android:style/TextAppearance.Material.Small"
android:layout_gravity="center_vertical"
android:textStyle="bold" />
<info.nightscout.androidaps.utils.NumberPicker
android:id="@+id/overview_temptarget_temptarget"
android:layout_width="130dp"
android:layout_height="40dp"
android:layout_gravity="center_vertical" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:width="120dp"
android:padding="10dp"
android:text="@string/careportal_newnstreatment_duration_label"
android:textAppearance="@android:style/TextAppearance.Material.Small"
android:textStyle="bold" />
<info.nightscout.androidaps.utils.NumberPicker
android:id="@+id/overview_temptarget_duration"
android:layout_width="130dp"
android:layout_height="40dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:gravity="start"
android:minWidth="45dp"
android:paddingStart="5dp"
android:paddingEnd="5dp"
android:text="@string/unit_minute_short"
android:textAppearance="?android:attr/textAppearanceSmall" />
</LinearLayout>
<include layout="@layout/datetime" />
<include layout="@layout/okcancel" />
</LinearLayout>
</ScrollView>