diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/ProfileLocal/LocalProfileFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/ProfileLocal/LocalProfileFragment.java index fb8e2166e0..a325f08ad2 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/ProfileLocal/LocalProfileFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/ProfileLocal/LocalProfileFragment.java @@ -4,6 +4,7 @@ package info.nightscout.androidaps.plugins.ProfileLocal; import android.app.Activity; import android.os.Bundle; import android.support.annotation.NonNull; +import android.support.v4.app.FragmentTransaction; import android.text.Editable; import android.text.TextWatcher; import android.view.LayoutInflater; @@ -48,45 +49,43 @@ public class LocalProfileFragment extends SubscriberFragment { TimeListEdit basalView; TimeListEdit targetView; Button profileswitchButton; + Button resetButton; + Button saveButton; + TextView invalidProfile; + Runnable save = () -> { + doEdit(); + if (basalView != null) { + basalView.updateLabel(MainApp.sResources.getString(R.string.nsprofileview_basal_label) + ": " + getSumLabel()); + } + }; + + TextWatcher textWatch = 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) { + LocalProfilePlugin.getPlugin().dia = SafeParse.stringToDouble(diaView.getText().toString()); + doEdit(); + } + }; + @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { try { - Runnable save = new Runnable() { - @Override - public void run() { - LocalProfilePlugin.getPlugin().storeSettings(); - if (basalView != null) { - basalView.updateLabel(MainApp.sResources.getString(R.string.nsprofileview_basal_label) + ": " + getSumLabel()); - } - updateGUI(); - } - }; - - TextWatcher textWatch = 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) { - LocalProfilePlugin.getPlugin().dia = SafeParse.stringToDouble(diaView.getText().toString()); - LocalProfilePlugin.getPlugin().storeSettings(); - updateGUI(); - } - }; PumpDescription pumpDescription = ConfigBuilderPlugin.getActivePump().getPumpDescription(); - View layout = inflater.inflate(R.layout.localprofile_fragment, container, false); diaView = (NumberPicker) layout.findViewById(R.id.localprofile_dia); diaView.setParams(LocalProfilePlugin.getPlugin().dia, 2d, 48d, 0.1d, new DecimalFormat("0.0"), false, textWatch); @@ -97,6 +96,10 @@ public class LocalProfileFragment extends SubscriberFragment { basalView = new TimeListEdit(getContext(), layout, R.id.localprofile_basal, MainApp.sResources.getString(R.string.nsprofileview_basal_label) + ": " + getSumLabel(), LocalProfilePlugin.getPlugin().basal, null, pumpDescription.basalMinimumRate, 10, 0.01d, new DecimalFormat("0.00"), save); targetView = new TimeListEdit(getContext(), layout, R.id.localprofile_target, MainApp.sResources.getString(R.string.nsprofileview_target_label) + ":", LocalProfilePlugin.getPlugin().targetLow, LocalProfilePlugin.getPlugin().targetHigh, 3d, 200, 0.1d, new DecimalFormat("0.0"), save); profileswitchButton = (Button) layout.findViewById(R.id.localprofile_profileswitch); + resetButton = (Button) layout.findViewById(R.id.localprofile_reset); + saveButton = (Button) layout.findViewById(R.id.localprofile_save); + + invalidProfile = (TextView) layout.findViewById(R.id.invalidprofile); if (!ConfigBuilderPlugin.getActivePump().getPumpDescription().isTempBasalCapable) { @@ -112,7 +115,7 @@ public class LocalProfileFragment extends SubscriberFragment { LocalProfilePlugin.getPlugin().mgdl = mgdlView.isChecked(); LocalProfilePlugin.getPlugin().mmol = !LocalProfilePlugin.getPlugin().mgdl; mmolView.setChecked(LocalProfilePlugin.getPlugin().mmol); - LocalProfilePlugin.getPlugin().storeSettings(); + doEdit(); } }); mmolView.setOnClickListener(new View.OnClickListener() { @@ -121,7 +124,7 @@ public class LocalProfileFragment extends SubscriberFragment { LocalProfilePlugin.getPlugin().mmol = mmolView.isChecked(); LocalProfilePlugin.getPlugin().mgdl = !LocalProfilePlugin.getPlugin().mmol; mgdlView.setChecked(LocalProfilePlugin.getPlugin().mgdl); - LocalProfilePlugin.getPlugin().storeSettings(); + doEdit(); } }); @@ -136,6 +139,25 @@ public class LocalProfileFragment extends SubscriberFragment { } }); + resetButton.setOnClickListener(view -> { + LocalProfilePlugin.getPlugin().loadSettings(); + mgdlView.setChecked(LocalProfilePlugin.getPlugin().mgdl); + mmolView.setChecked(LocalProfilePlugin.getPlugin().mmol); + diaView.setParams(LocalProfilePlugin.getPlugin().dia, 2d, 48d, 0.1d, new DecimalFormat("0.0"), false, textWatch); + icView = new TimeListEdit(getContext(), layout, R.id.localprofile_ic, MainApp.sResources.getString(R.string.nsprofileview_ic_label) + ":", LocalProfilePlugin.getPlugin().ic, null, 0.5, 50d, 0.1d, new DecimalFormat("0.0"), save); + isfView = new TimeListEdit(getContext(), layout, R.id.localprofile_isf, MainApp.sResources.getString(R.string.nsprofileview_isf_label) + ":", LocalProfilePlugin.getPlugin().isf, null, 0.5, 500d, 0.1d, new DecimalFormat("0.0"), save); + basalView = new TimeListEdit(getContext(), layout, R.id.localprofile_basal, MainApp.sResources.getString(R.string.nsprofileview_basal_label) + ": " + getSumLabel(), LocalProfilePlugin.getPlugin().basal, null, pumpDescription.basalMinimumRate, 10, 0.01d, new DecimalFormat("0.00"), save); + targetView = new TimeListEdit(getContext(), layout, R.id.localprofile_target, MainApp.sResources.getString(R.string.nsprofileview_target_label) + ":", LocalProfilePlugin.getPlugin().targetLow, LocalProfilePlugin.getPlugin().targetHigh, 3d, 200, 0.1d, new DecimalFormat("0.0"), save); + updateGUI(); + }); + + saveButton.setOnClickListener(view -> { + if(!LocalProfilePlugin.getPlugin().isValidEditState()){ + return; //Should not happen as saveButton should not be visible if not valid + } + LocalProfilePlugin.getPlugin().storeSettings(); + updateGUI(); + }); return layout; } catch (Exception e) { @@ -146,9 +168,14 @@ public class LocalProfileFragment extends SubscriberFragment { return null; } + public void doEdit() { + LocalProfilePlugin.getPlugin().setEdited(true); + updateGUI(); + } + @NonNull public String getSumLabel() { - ProfileStore profile = LocalProfilePlugin.getPlugin().getProfile(); + ProfileStore profile = LocalProfilePlugin.getPlugin().createProfileStore(); if (profile != null) return " ∑" + DecimalFormatter.to2Decimal(profile.getDefaultProfile().baseBasalSum()) + "U"; else @@ -167,16 +194,39 @@ public class LocalProfileFragment extends SubscriberFragment { activity.runOnUiThread(new Runnable() { @Override public void run() { - boolean isValid = LocalProfilePlugin.getPlugin().getProfile() != null && LocalProfilePlugin.getPlugin().getProfile().getDefaultProfile().isValid(MainApp.gs(R.string.localprofile)); - if (!ConfigBuilderPlugin.getActivePump().isInitialized() || ConfigBuilderPlugin.getActivePump().isSuspended() || !isValid) { - profileswitchButton.setVisibility(View.GONE); + boolean isValid = LocalProfilePlugin.getPlugin().isValidEditState(); + boolean isEdited = LocalProfilePlugin.getPlugin().isEdited(); + if (isValid) { + invalidProfile.setVisibility(View.GONE); //show invalid profile + + if (isEdited || !ConfigBuilderPlugin.getActivePump().isInitialized() || ConfigBuilderPlugin.getActivePump().isSuspended()) { + //edited profile -> save first + //pump not initialized -> don't update profile yet + profileswitchButton.setVisibility(View.GONE); + } else { + profileswitchButton.setVisibility(View.VISIBLE); + } + + if(isEdited){ + saveButton.setVisibility(View.VISIBLE); + } else { + saveButton.setVisibility(View.GONE); + + } + + } else { - profileswitchButton.setVisibility(View.VISIBLE); - } - if (isValid) - invalidProfile.setVisibility(View.GONE); - else invalidProfile.setVisibility(View.VISIBLE); + profileswitchButton.setVisibility(View.GONE); + saveButton.setVisibility(View.GONE); //don't save an invalid profile + } + + //Show reset button iff data was edited + if(isEdited) { + resetButton.setVisibility(View.VISIBLE); + } else { + resetButton.setVisibility(View.GONE); + } } }); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/ProfileLocal/LocalProfilePlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/ProfileLocal/LocalProfilePlugin.java index 512d452289..30e0d9b064 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/ProfileLocal/LocalProfilePlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/ProfileLocal/LocalProfilePlugin.java @@ -2,6 +2,7 @@ package info.nightscout.androidaps.plugins.ProfileLocal; import android.content.SharedPreferences; import android.preference.PreferenceManager; +import android.support.annotation.NonNull; import org.json.JSONArray; import org.json.JSONException; @@ -40,6 +41,15 @@ public class LocalProfilePlugin extends PluginBase implements ProfileInterface { private static final String DEFAULTARRAY = "[{\"time\":\"00:00\",\"timeAsSeconds\":0,\"value\":0}]"; + public boolean isEdited() { + return edited; + } + + public void setEdited(boolean edited) { + this.edited = edited; + } + + boolean edited; boolean mgdl; boolean mmol; Double dia; @@ -59,7 +69,7 @@ public class LocalProfilePlugin extends PluginBase implements ProfileInterface { loadSettings(); } - public void storeSettings() { + public synchronized void storeSettings() { SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(MainApp.instance().getApplicationContext()); SharedPreferences.Editor editor = settings.edit(); editor.putBoolean(LOCAL_PROFILE + "mmol", mmol); @@ -72,12 +82,13 @@ public class LocalProfilePlugin extends PluginBase implements ProfileInterface { editor.putString(LOCAL_PROFILE + "targethigh", targetHigh.toString()); editor.apply(); - createConvertedProfile(); + createAndStoreConvertedProfile(); + edited = false; if (Config.logPrefsChange) log.debug("Storing settings: " + getRawProfile().getData().toString()); } - public void loadSettings() { + public synchronized void loadSettings() { if (Config.logPrefsChange) log.debug("Loading stored settings"); @@ -124,6 +135,8 @@ public class LocalProfilePlugin extends PluginBase implements ProfileInterface { } catch (JSONException ignored) { } } + edited = false; + createAndStoreConvertedProfile(); } /* @@ -164,7 +177,16 @@ public class LocalProfilePlugin extends PluginBase implements ProfileInterface { "created_at": "2016-06-16T08:34:41.256Z" } */ - private void createConvertedProfile() { + private void createAndStoreConvertedProfile() { + convertedProfile = createProfileStore(); + } + + public synchronized boolean isValidEditState() { + return createProfileStore().getDefaultProfile().isValid(MainApp.gs(R.string.localprofile)); + } + + @NonNull + public ProfileStore createProfileStore() { JSONObject json = new JSONObject(); JSONObject store = new JSONObject(); JSONObject profile = new JSONObject(); @@ -183,21 +205,17 @@ public class LocalProfilePlugin extends PluginBase implements ProfileInterface { } catch (JSONException e) { log.error("Unhandled exception", e); } - convertedProfile = new ProfileStore(json); + return new ProfileStore(json); } @Override public ProfileStore getProfile() { - if (convertedProfile == null) - createConvertedProfile(); if (!convertedProfile.getDefaultProfile().isValid(MainApp.gs(R.string.localprofile))) return null; return convertedProfile; } public ProfileStore getRawProfile() { - if (convertedProfile == null) - createConvertedProfile(); return convertedProfile; } @@ -208,8 +226,6 @@ public class LocalProfilePlugin extends PluginBase implements ProfileInterface { @Override public String getProfileName() { - if (convertedProfile == null) - createConvertedProfile(); return DecimalFormatter.to2Decimal(convertedProfile.getDefaultProfile().percentageBasalSum()) + "U "; } diff --git a/app/src/main/java/info/nightscout/utils/NumberPicker.java b/app/src/main/java/info/nightscout/utils/NumberPicker.java index 53ffd90f7b..01c7dcb336 100644 --- a/app/src/main/java/info/nightscout/utils/NumberPicker.java +++ b/app/src/main/java/info/nightscout/utils/NumberPicker.java @@ -148,6 +148,9 @@ public class NumberPicker extends LinearLayout implements View.OnKeyListener, } public void setParams(Double initValue, Double minValue, Double maxValue, Double step, NumberFormat formater, boolean allowZero, TextWatcher textWatcher) { + if(this.textWatcher != null) { + editText.removeTextChangedListener(this.textWatcher); + } setParams(initValue, minValue, maxValue, step, formater, allowZero); this.textWatcher = textWatcher; editText.addTextChangedListener(textWatcher); diff --git a/app/src/main/java/info/nightscout/utils/TimeListEdit.java b/app/src/main/java/info/nightscout/utils/TimeListEdit.java index bc41ece59d..ec03734b18 100644 --- a/app/src/main/java/info/nightscout/utils/TimeListEdit.java +++ b/app/src/main/java/info/nightscout/utils/TimeListEdit.java @@ -78,6 +78,7 @@ public class TimeListEdit { private void buildView() { layout = (LinearLayout) view.findViewById(resLayoutId); + layout.removeAllViews(); textlabel = new TextView(context); textlabel.setText(label); diff --git a/app/src/main/res/layout/localprofile_fragment.xml b/app/src/main/res/layout/localprofile_fragment.xml index 4b61e0235d..a08c6964e9 100644 --- a/app/src/main/res/layout/localprofile_fragment.xml +++ b/app/src/main/res/layout/localprofile_fragment.xml @@ -153,6 +153,43 @@ android:text="@string/activate_profile" android:textColor="@color/colorProfileSwitchButton" /> + +