diff --git a/app/build.gradle b/app/build.gradle
index 15015ca255..596ca090e6 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -49,8 +49,8 @@ def generateGitBuild = { ->
return stringBuilder.toString()
}
-tasks.matching {it instanceof Test}.all {
- testLogging.events = ["failed", "skipped"]
+tasks.matching { it instanceof Test }.all {
+ testLogging.events = ["failed", "skipped", "started"]
testLogging.exceptionFormat = "full"
}
@@ -89,7 +89,7 @@ android {
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
debug {
- testCoverageEnabled (project.hasProperty('coverage') ? true : false)
+ testCoverageEnabled(project.hasProperty('coverage') ? true : false)
}
}
productFlavors {
@@ -156,7 +156,7 @@ android {
unitTests.returnDefaultValues = true
unitTests.includeAndroidResources = true
}
- }
+}
allprojects {
repositories {
@@ -172,6 +172,7 @@ configurations {
}
dependencies {
+ implementation 'com.android.support:support-v4:27.1.1'
wearApp project(':wear')
implementation fileTree(include: ['*.jar'], dir: 'libs')
@@ -242,7 +243,7 @@ dependencies {
}
task unzip(type: Copy) {
- def zipPath = configurations.libs.find {it.name.startsWith("danars") }
+ def zipPath = configurations.libs.find { it.name.startsWith("danars") }
def zipFile = file(zipPath)
def outputDir = file("${buildDir}/unpacked/dist")
@@ -263,4 +264,4 @@ task full_clean(type: Delete) {
}
clean.dependsOn full_clean
-preBuild.dependsOn copyLibs
\ No newline at end of file
+preBuild.dependsOn copyLibs
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 00d59f09bb..a65f92d7b3 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -51,12 +51,14 @@
+
+
@@ -68,6 +70,7 @@
android:enabled="true"
android:exported="true">
+
@@ -130,7 +133,7 @@
+ android:exported="true" />
@@ -148,12 +151,17 @@
android:exported="true" />
+ android:exported="false" />
+
\ No newline at end of file
diff --git a/app/src/main/java/info/nightscout/androidaps/Config.java b/app/src/main/java/info/nightscout/androidaps/Config.java
index ff7b935355..afb40421df 100644
--- a/app/src/main/java/info/nightscout/androidaps/Config.java
+++ b/app/src/main/java/info/nightscout/androidaps/Config.java
@@ -37,6 +37,7 @@ public class Config {
public static final boolean logCongigBuilderActions = true;
public static final boolean logAutosensData = false;
public static final boolean logEvents = false;
+ public static final boolean logProfile = false;
// DanaR specific
public static final boolean logDanaBTComm = true;
diff --git a/app/src/main/java/info/nightscout/androidaps/MainActivity.java b/app/src/main/java/info/nightscout/androidaps/MainActivity.java
index 440024f853..a902ca7091 100644
--- a/app/src/main/java/info/nightscout/androidaps/MainActivity.java
+++ b/app/src/main/java/info/nightscout/androidaps/MainActivity.java
@@ -49,6 +49,7 @@ import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.Food.FoodPlugin;
import info.nightscout.androidaps.plugins.Overview.events.EventSetWakeLock;
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
+import info.nightscout.androidaps.startupwizard.SetupWizardActivity;
import info.nightscout.androidaps.tabs.SlidingTabLayout;
import info.nightscout.androidaps.tabs.TabPageAdapter;
import info.nightscout.utils.ImportExportPrefs;
@@ -368,6 +369,9 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
case R.id.nav_historybrowser:
startActivity(new Intent(v.getContext(), HistoryBrowseActivity.class));
break;
+ case R.id.nav_setupwizard:
+ startActivity(new Intent(v.getContext(), SetupWizardActivity.class));
+ break;
case R.id.nav_resetdb:
new AlertDialog.Builder(v.getContext())
.setTitle(R.string.nav_resetdb)
diff --git a/app/src/main/java/info/nightscout/androidaps/Services/DataService.java b/app/src/main/java/info/nightscout/androidaps/Services/DataService.java
index 6a771fc4a1..3e0bbf9c74 100644
--- a/app/src/main/java/info/nightscout/androidaps/Services/DataService.java
+++ b/app/src/main/java/info/nightscout/androidaps/Services/DataService.java
@@ -197,7 +197,8 @@ public class DataService extends IntentService {
bgReading.direction = bundle.getString(Intents.EXTRA_BG_SLOPE_NAME);
bgReading.date = bundle.getLong(Intents.EXTRA_TIMESTAMP);
bgReading.raw = bundle.getDouble(Intents.EXTRA_RAW);
-
+ String source = bundle.getString(Intents.XDRIP_DATA_SOURCE_DESCRIPTION, "no Source specified");
+ SourceXdripPlugin.getPlugin().setSource(source);
MainApp.getDbHelper().createIfNotExists(bgReading, "XDRIP");
}
diff --git a/app/src/main/java/info/nightscout/androidaps/Services/Intents.java b/app/src/main/java/info/nightscout/androidaps/Services/Intents.java
index b9c90e905c..744530c8f2 100644
--- a/app/src/main/java/info/nightscout/androidaps/Services/Intents.java
+++ b/app/src/main/java/info/nightscout/androidaps/Services/Intents.java
@@ -37,6 +37,8 @@ public interface Intents {
String EXTRA_SENSOR_BATTERY = "com.eveningoutpost.dexdrip.Extras.SensorBattery";
String EXTRA_TIMESTAMP = "com.eveningoutpost.dexdrip.Extras.Time";
String EXTRA_RAW = "com.eveningoutpost.dexdrip.Extras.Raw";
+ String XDRIP_DATA_SOURCE_DESCRIPTION = "com.eveningoutpost.dexdrip.Extras.SourceDesc";
+
String ACTION_NEW_BG_ESTIMATE_NO_DATA = "com.eveningoutpost.dexdrip.BgEstimateNoData";
diff --git a/app/src/main/java/info/nightscout/androidaps/data/DetailedBolusInfo.java b/app/src/main/java/info/nightscout/androidaps/data/DetailedBolusInfo.java
index 3935b17b8a..c2f9d16dc3 100644
--- a/app/src/main/java/info/nightscout/androidaps/data/DetailedBolusInfo.java
+++ b/app/src/main/java/info/nightscout/androidaps/data/DetailedBolusInfo.java
@@ -30,6 +30,7 @@ public class DetailedBolusInfo {
public long pumpId = 0; // id of record if comming from pump history (not a newly created treatment)
public boolean isSMB = false; // is a Super-MicroBolus
public long deliverAt = 0; // SMB should be delivered within 1 min from this time
+ public String notes = null;
public DetailedBolusInfo copy() {
DetailedBolusInfo n = new DetailedBolusInfo();
@@ -47,6 +48,7 @@ public class DetailedBolusInfo {
n.pumpId = pumpId;
n.isSMB = isSMB;
n.deliverAt = deliverAt;
+ n.notes = notes;
return n;
}
diff --git a/app/src/main/java/info/nightscout/androidaps/data/Profile.java b/app/src/main/java/info/nightscout/androidaps/data/Profile.java
index e966c4d11d..783124168f 100644
--- a/app/src/main/java/info/nightscout/androidaps/data/Profile.java
+++ b/app/src/main/java/info/nightscout/androidaps/data/Profile.java
@@ -12,6 +12,7 @@ import java.text.DecimalFormat;
import java.util.Calendar;
import java.util.TimeZone;
+import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.Constants;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
@@ -275,7 +276,7 @@ public class Profile {
Integer getShitfTimeSecs(Integer originalTime) {
Integer shiftedTime = originalTime + timeshift * 60 * 60;
shiftedTime = (shiftedTime + 24 * 60 * 60) % (24 * 60 * 60);
- if (timeshift != 0)
+ if (timeshift != 0 && Config.logProfile)
log.debug("(Sec) Original time: " + originalTime + " ShiftedTime: " + shiftedTime);
return shiftedTime;
}
diff --git a/app/src/main/java/info/nightscout/androidaps/data/QuickWizardEntry.java b/app/src/main/java/info/nightscout/androidaps/data/QuickWizardEntry.java
index 4a94db0a44..e4cd50c490 100644
--- a/app/src/main/java/info/nightscout/androidaps/data/QuickWizardEntry.java
+++ b/app/src/main/java/info/nightscout/androidaps/data/QuickWizardEntry.java
@@ -11,7 +11,6 @@ import info.nightscout.androidaps.R;
import info.nightscout.androidaps.db.BgReading;
import info.nightscout.androidaps.db.TempTarget;
import info.nightscout.androidaps.interfaces.TreatmentsInterface;
-import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.IobCobCalculator.AutosensData;
import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin;
import info.nightscout.androidaps.plugins.Loop.LoopPlugin;
@@ -119,8 +118,8 @@ public class QuickWizardEntry {
if (useSuperBolus() == YES && SP.getBoolean(R.string.key_usesuperbolus, false)) {
superBolus = true;
}
- final LoopPlugin activeloop = ConfigBuilderPlugin.getActiveLoop();
- if (activeloop != null && activeloop.isEnabled(activeloop.getType()) && activeloop.isSuperBolus())
+ final LoopPlugin loopPlugin = LoopPlugin.getPlugin();
+ if (loopPlugin.isEnabled(loopPlugin.getType()) && loopPlugin.isSuperBolus())
superBolus = false;
// Trend
diff --git a/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java b/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java
index 75e830e654..7174c19ec4 100644
--- a/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java
+++ b/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java
@@ -28,6 +28,7 @@ import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import info.nightscout.androidaps.Config;
+import info.nightscout.androidaps.Constants;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.data.ProfileStore;
@@ -45,6 +46,7 @@ import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventNewHistor
import info.nightscout.androidaps.plugins.PumpDanaR.activities.DanaRNSHistorySync;
import info.nightscout.androidaps.plugins.PumpDanaR.comm.RecordTypes;
import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin;
+import info.nightscout.utils.JsonHelper;
import info.nightscout.utils.NSUpload;
import info.nightscout.utils.PercentageSplitter;
import info.nightscout.utils.ToastUtils;
@@ -662,7 +664,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
public void createTemptargetFromJsonIfNotExists(JSONObject trJson) {
try {
- String units = MainApp.getConfigBuilder().getProfileUnits();
+ String units = JsonHelper.safeGetString(trJson, "units", MainApp.getConfigBuilder().getProfileUnits());
TempTarget tempTarget = new TempTarget()
.date(trJson.getLong("mills"))
.duration(trJson.getInt("duration"))
diff --git a/app/src/main/java/info/nightscout/androidaps/interfaces/TreatmentsInterface.java b/app/src/main/java/info/nightscout/androidaps/interfaces/TreatmentsInterface.java
index 30610ca2f6..27a6a0846b 100644
--- a/app/src/main/java/info/nightscout/androidaps/interfaces/TreatmentsInterface.java
+++ b/app/src/main/java/info/nightscout/androidaps/interfaces/TreatmentsInterface.java
@@ -55,6 +55,7 @@ public interface TreatmentsInterface {
TempTarget getTempTargetFromHistory();
TempTarget getTempTargetFromHistory(long time);
Intervals getTempTargetsFromHistory();
+ void addToHistoryTempTarget(TempTarget tempTarget);
ProfileSwitch getProfileSwitchFromHistory(long time);
ProfileIntervals getProfileSwitchesFromHistory();
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Actions/dialogs/FillDialog.java b/app/src/main/java/info/nightscout/androidaps/plugins/Actions/dialogs/FillDialog.java
index b3b15bf7fb..5e99a6ca17 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/Actions/dialogs/FillDialog.java
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/Actions/dialogs/FillDialog.java
@@ -5,7 +5,9 @@ import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.support.v7.app.AlertDialog;
+import android.text.Editable;
import android.text.Html;
+import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
@@ -14,6 +16,8 @@ import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.CheckBox;
+import android.widget.EditText;
+import android.widget.LinearLayout;
import com.crashlytics.android.answers.CustomEvent;
import com.google.common.base.Joiner;
@@ -21,8 +25,6 @@ import com.google.common.base.Joiner;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import info.nightscout.androidaps.Constants;
-import java.text.DecimalFormat;
import java.util.LinkedList;
import java.util.List;
@@ -41,19 +43,45 @@ import info.nightscout.utils.NSUpload;
import info.nightscout.utils.NumberPicker;
import info.nightscout.utils.SP;
import info.nightscout.utils.SafeParse;
+import info.nightscout.utils.ToastUtils;
+
+import static info.nightscout.utils.DateUtil.now;
public class FillDialog extends DialogFragment implements OnClickListener {
private static Logger log = LoggerFactory.getLogger(FillDialog.class);
+ private CheckBox pumpSiteChangeCheckbox;
+ private CheckBox insulinCartridgeChangeCheckbox;
+
+ private NumberPicker editInsulin;
+
double amount1 = 0d;
double amount2 = 0d;
double amount3 = 0d;
- NumberPicker editInsulin;
- CheckBox pumpSiteChangeCheckbox;
- CheckBox insulinCartridgeChangeCheckbox;
+ private EditText notesEdit;
- public FillDialog() {
+ final private TextWatcher textWatcher = new TextWatcher() {
+ @Override
+ public void afterTextChanged(Editable s) {
+ validateInputs();
+ }
+
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+ }
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ }
+ };
+
+ private void validateInputs() {
+ int time = editInsulin.getValue().intValue();
+ if (Math.abs(time) > 12 * 60) {
+ editInsulin.setValue(0d);
+ ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.constraintapllied));
+ }
}
@Override
@@ -67,45 +95,47 @@ public class FillDialog extends DialogFragment implements OnClickListener {
getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
- pumpSiteChangeCheckbox = view.findViewById(R.id.catheter_change);
- insulinCartridgeChangeCheckbox = view.findViewById(R.id.cartridge_change);
+ pumpSiteChangeCheckbox = view.findViewById(R.id.fill_catheter_change);
+ insulinCartridgeChangeCheckbox = view.findViewById(R.id.fill_cartridge_change);
Double maxInsulin = MainApp.getConstraintChecker().getMaxBolusAllowed().value();
double bolusstep = ConfigBuilderPlugin.getActivePump().getPumpDescription().bolusStep;
- editInsulin = view.findViewById(R.id.treatments_newtreatment_insulinamount);
- editInsulin.setParams(0d, 0d, maxInsulin, bolusstep, DecimalFormatter.pumpSupportedBolusFormat(), false);
+ editInsulin = view.findViewById(R.id.fill_insulinamount);
+ editInsulin.setParams(0d, 0d, maxInsulin, bolusstep, DecimalFormatter.pumpSupportedBolusFormat(), false, textWatcher);
- //setup preset buttons
- Button button1 = (Button) view.findViewById(R.id.fill_preset_button1);
- Button button2 = (Button) view.findViewById(R.id.fill_preset_button2);
- Button button3 = (Button) view.findViewById(R.id.fill_preset_button3);
+ Button preset1Button = view.findViewById(R.id.fill_preset_button1);
amount1 = SP.getDouble("fill_button1", 0.3);
- amount2 = SP.getDouble("fill_button2", 0d);
- amount3 = SP.getDouble("fill_button3", 0d);
-
if (amount1 > 0) {
- button1.setVisibility(View.VISIBLE);
- button1.setText(DecimalFormatter.toPumpSupportedBolus(amount1)); // + "U");
- button1.setOnClickListener(this);
+ preset1Button.setVisibility(View.VISIBLE);
+ preset1Button.setText(DecimalFormatter.toPumpSupportedBolus(amount1)); // + "U");
+ preset1Button.setOnClickListener(this);
} else {
- button1.setVisibility(View.GONE);
+ preset1Button.setVisibility(View.GONE);
}
+ Button preset2Button = view.findViewById(R.id.fill_preset_button2);
+ amount2 = SP.getDouble("fill_button2", 0d);
if (amount2 > 0) {
- button2.setVisibility(View.VISIBLE);
- button2.setText(DecimalFormatter.toPumpSupportedBolus(amount2)); // + "U");
- button2.setOnClickListener(this);
+ preset2Button.setVisibility(View.VISIBLE);
+ preset2Button.setText(DecimalFormatter.toPumpSupportedBolus(amount2)); // + "U");
+ preset2Button.setOnClickListener(this);
} else {
- button2.setVisibility(View.GONE);
+ preset2Button.setVisibility(View.GONE);
}
+ Button preset3Button = view.findViewById(R.id.fill_preset_button3);
+ amount3 = SP.getDouble("fill_button3", 0d);
if (amount3 > 0) {
- button3.setVisibility(View.VISIBLE);
- button3.setText(DecimalFormatter.toPumpSupportedBolus(amount3)); // + "U");
- button3.setOnClickListener(this);
+ preset3Button.setVisibility(View.VISIBLE);
+ preset3Button.setText(DecimalFormatter.toPumpSupportedBolus(amount3)); // + "U");
+ preset3Button.setOnClickListener(this);
} else {
- button3.setVisibility(View.GONE);
+ preset3Button.setVisibility(View.GONE);
}
+ LinearLayout notesLayout = view.findViewById(R.id.fill_notes_layout);
+ notesLayout.setVisibility(SP.getBoolean(R.string.key_show_notes_entry_dialogs, false) ? View.VISIBLE : View.GONE);
+ notesEdit = view.findViewById(R.id.fill_notes);
+
setCancelable(true);
getDialog().setCanceledOnTouchOutside(false);
return view;
@@ -154,42 +184,50 @@ public class FillDialog extends DialogFragment implements OnClickListener {
if (insulinCartridgeChangeCheckbox.isChecked())
confirmMessage.add("" + "" + getString(R.string.record_insulin_cartridge_change) + "");
+ final String notes = notesEdit.getText().toString();
+ if (!notes.isEmpty()) {
+ confirmMessage.add(MainApp.gs(R.string.careportal_newnstreatment_notes_label) + ": " + notes);
+ }
+
final Double finalInsulinAfterConstraints = insulinAfterConstraints;
final Context context = getContext();
AlertDialog.Builder builder = new AlertDialog.Builder(context);
- if (confirmMessage.isEmpty())
- confirmMessage.add(MainApp.gs(R.string.no_action_selected));
-
builder.setTitle(MainApp.gs(R.string.confirmation));
- builder.setMessage(Html.fromHtml(Joiner.on("
").join(confirmMessage)));
- builder.setPositiveButton(getString(R.string.primefill), (dialog, id) -> {
- if (finalInsulinAfterConstraints > 0) {
- DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo();
- detailedBolusInfo.insulin = finalInsulinAfterConstraints;
- detailedBolusInfo.context = context;
- detailedBolusInfo.source = Source.USER;
- detailedBolusInfo.isValid = false; // do not count it in IOB (for pump history)
- ConfigBuilderPlugin.getCommandQueue().bolus(detailedBolusInfo, new Callback() {
- @Override
- public void run() {
- if (!result.success) {
- Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class);
- i.putExtra("soundid", R.raw.boluserror);
- i.putExtra("status", result.comment);
- i.putExtra("title", MainApp.sResources.getString(R.string.treatmentdeliveryerror));
- i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- MainApp.instance().startActivity(i);
+ if (insulinAfterConstraints > 0 || pumpSiteChangeCheckbox.isChecked() || insulinCartridgeChangeCheckbox.isChecked()) {
+ builder.setMessage(Html.fromHtml(Joiner.on("
").join(confirmMessage)));
+ builder.setPositiveButton(getString(R.string.primefill), (dialog, id) -> {
+ if (finalInsulinAfterConstraints > 0) {
+ DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo();
+ detailedBolusInfo.insulin = finalInsulinAfterConstraints;
+ detailedBolusInfo.context = context;
+ detailedBolusInfo.source = Source.USER;
+ detailedBolusInfo.isValid = false; // do not count it in IOB (for pump history)
+ detailedBolusInfo.notes = notes;
+ ConfigBuilderPlugin.getCommandQueue().bolus(detailedBolusInfo, new Callback() {
+ @Override
+ public void run() {
+ if (!result.success) {
+ Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class);
+ i.putExtra("soundid", R.raw.boluserror);
+ i.putExtra("status", result.comment);
+ i.putExtra("title", MainApp.sResources.getString(R.string.treatmentdeliveryerror));
+ i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ MainApp.instance().startActivity(i);
+ }
}
- }
- });
- FabricPrivacy.getInstance().logCustom(new CustomEvent("Fill"));
- }
- long now = System.currentTimeMillis();
- if (pumpSiteChangeCheckbox.isChecked()) NSUpload.uploadEvent(CareportalEvent.SITECHANGE, now);
- if (insulinCartridgeChangeCheckbox.isChecked()) NSUpload.uploadEvent(CareportalEvent.INSULINCHANGE, now + 1000);
- });
+ });
+ FabricPrivacy.getInstance().logCustom(new CustomEvent("Fill"));
+ }
+ if (pumpSiteChangeCheckbox.isChecked())
+ NSUpload.uploadEvent(CareportalEvent.SITECHANGE, now(), notes);
+ if (insulinCartridgeChangeCheckbox.isChecked())
+ NSUpload.uploadEvent(CareportalEvent.INSULINCHANGE, now() + 1000, notes);
+ });
+ } else {
+ builder.setMessage(MainApp.gs(R.string.no_action_selected));
+ }
builder.setNegativeButton(getString(R.string.cancel), null);
builder.show();
dismiss();
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Careportal/Dialogs/NewNSTreatmentDialog.java b/app/src/main/java/info/nightscout/androidaps/plugins/Careportal/Dialogs/NewNSTreatmentDialog.java
index 61122fb0c2..56aa0158cf 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/Careportal/Dialogs/NewNSTreatmentDialog.java
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/Careportal/Dialogs/NewNSTreatmentDialog.java
@@ -2,7 +2,6 @@ package info.nightscout.androidaps.plugins.Careportal.Dialogs;
import android.app.Activity;
-import android.content.DialogInterface;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.support.v7.app.AlertDialog;
@@ -15,7 +14,6 @@ import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
-import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.RadioButton;
@@ -23,6 +21,7 @@ import android.widget.Spinner;
import android.widget.TextView;
import com.crashlytics.android.answers.CustomEvent;
+import com.google.common.collect.Lists;
import com.wdullaer.materialdatetimepicker.date.DatePickerDialog;
import com.wdullaer.materialdatetimepicker.time.RadialPickerLayout;
import com.wdullaer.materialdatetimepicker.time.TimePickerDialog;
@@ -52,8 +51,10 @@ import info.nightscout.androidaps.db.TempTarget;
import info.nightscout.androidaps.plugins.Careportal.OptionsToShow;
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
import info.nightscout.utils.DateUtil;
+import info.nightscout.utils.DefaultValueHelper;
import info.nightscout.utils.FabricPrivacy;
import info.nightscout.utils.HardLimits;
+import info.nightscout.utils.JsonHelper;
import info.nightscout.utils.NSUpload;
import info.nightscout.utils.NumberPicker;
import info.nightscout.utils.SP;
@@ -69,7 +70,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
private static String event;
Profile profile;
- ProfileStore profileStore;
+ public ProfileStore profileStore;
String units = Constants.MGDL;
TextView eventTypeText;
@@ -108,14 +109,14 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
public void setOptions(OptionsToShow options, int event) {
this.options = options;
- this.event = MainApp.sResources.getString(event);
+ this.event = MainApp.gs(event);
}
public NewNSTreatmentDialog() {
super();
if (seconds == null) {
- seconds = new Double(Math.random() * 59).intValue();
+ seconds = Double.valueOf(Math.random() * 59).intValue();
}
}
@@ -135,7 +136,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (options == null) return null;
- getDialog().setTitle(getString(options.eventName));
+ getDialog().setTitle(MainApp.gs(options.eventName));
setStyle(DialogFragment.STYLE_NORMAL, getTheme());
View view = inflater.inflate(R.layout.careportal_newnstreatment_dialog, container, false);
@@ -192,36 +193,40 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
final Double bg = Profile.fromMgdlToUnits(GlucoseStatus.getGlucoseStatusData() != null ? GlucoseStatus.getGlucoseStatusData().glucose : 0d, units);
// temp target
- final ArrayList reasonList = new ArrayList();
- reasonList.add(MainApp.sResources.getString(R.string.manual));
- reasonList.add(MainApp.sResources.getString(R.string.eatingsoon));
- reasonList.add(MainApp.sResources.getString(R.string.activity));
- ArrayAdapter adapterReason = new ArrayAdapter(getContext(),
+ final List reasonList = Lists.newArrayList(
+ MainApp.gs(R.string.manual),
+ MainApp.gs(R.string.eatingsoon),
+ MainApp.gs(R.string.activity),
+ MainApp.gs(R.string.hypo));
+ ArrayAdapter adapterReason = new ArrayAdapter<>(getContext(),
R.layout.spinner_centered, reasonList);
reasonSpinner.setAdapter(adapterReason);
reasonSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView> parent, View view, int position, long id) {
- double defaultDuration = 0;
+ double defaultDuration;
double defaultTarget = 0;
if (profile != null) {
- defaultTarget = bg.doubleValue();
+ defaultTarget = bg;
}
boolean erase = false;
- if (MainApp.sResources.getString(R.string.eatingsoon).equals(reasonList.get(position))) {
- defaultDuration = SP.getDouble(R.string.key_eatingsoon_duration, 0d);
- defaultTarget = SP.getDouble(R.string.key_eatingsoon_target, 0d);
- ;
- } else if (MainApp.sResources.getString(R.string.activity).equals(reasonList.get(position))) {
- defaultDuration = SP.getDouble(R.string.key_activity_duration, 0d);
- ;
- defaultTarget = SP.getDouble(R.string.key_activity_target, 0d);
- ;
+ String units = MainApp.getConfigBuilder().getProfileUnits();
+ DefaultValueHelper helper = new DefaultValueHelper();
+ if (MainApp.gs(R.string.eatingsoon).equals(reasonList.get(position))) {
+ defaultDuration = helper.determineEatingSoonTTDuration();
+ defaultTarget = helper.determineEatingSoonTT(units);
+ } else if (MainApp.gs(R.string.activity).equals(reasonList.get(position))) {
+ defaultDuration = helper.determineActivityTTDuration();
+ defaultTarget = helper.determineActivityTT(units);
+ } else if (MainApp.gs(R.string.hypo).equals(reasonList.get(position))) {
+ defaultDuration = helper.determineHypoTTDuration();
+ defaultTarget = helper.determineHypoTT(units);
} else {
defaultDuration = 0;
erase = true;
}
+
if (defaultTarget != 0 || erase) {
editTemptarget.setValue(defaultTarget);
}
@@ -266,12 +271,9 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
editBg.setParams(bg, 0d, 500d, 1d, new DecimalFormat("0"), false, bgTextWatcher);
editTemptarget.setParams(bg, 0d, 500d, 1d, new DecimalFormat("0"), false);
}
- sensorRadioButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
- @Override
- public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
- Double bg = Profile.fromMgdlToUnits(GlucoseStatus.getGlucoseStatusData() != null ? GlucoseStatus.getGlucoseStatusData().glucose : 0d, profile.getUnits());
- editBg.setValue(bg);
- }
+ sensorRadioButton.setOnCheckedChangeListener((buttonView, isChecked) -> {
+ Double bg1 = Profile.fromMgdlToUnits(GlucoseStatus.getGlucoseStatusData() != null ? GlucoseStatus.getGlucoseStatusData().glucose : 0d, profile.getUnits());
+ editBg.setValue(bg1);
});
Integer maxCarbs = MainApp.getConstraintChecker().getMaxCarbsAllowed().value();
@@ -407,7 +409,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
tpd.show(context.getFragmentManager(), "Timepickerdialog");
break;
case R.id.ok:
- createNSTreatment();
+ confirmNSTreatmentCreation();
dismiss();
break;
case R.id.cancel:
@@ -571,158 +573,151 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
String buildConfirmText(JSONObject data) {
String ret = "";
- try {
- if (data.has("eventType")) {
- ret += getString(R.string.careportal_newnstreatment_eventtype);
- ret += ": ";
- ret += Translator.translate(data.getString("eventType"));
- ret += "\n";
- }
- if (data.has("glucose")) {
- ret += getString(R.string.treatments_wizard_bg_label);
- ret += ": ";
- ret += data.get("glucose");
- ret += " " + units + "\n";
- }
- if (data.has("glucoseType")) {
- ret += getString(R.string.careportal_newnstreatment_glucosetype);
- ret += ": ";
- ret += Translator.translate(data.getString("glucoseType"));
- ret += "\n";
- }
- if (data.has("carbs")) {
- ret += getString(R.string.careportal_newnstreatment_carbs_label);
- ret += ": ";
- ret += data.get("carbs");
- ret += " g\n";
- }
- if (data.has("insulin")) {
- ret += getString(R.string.careportal_newnstreatment_insulin_label);
- ret += ": ";
- ret += data.get("insulin");
- ret += " U\n";
- }
- if (data.has("duration")) {
- ret += getString(R.string.careportal_newnstreatment_duration_label);
- ret += ": ";
- ret += data.get("duration");
- ret += " min\n";
- }
- if (data.has("percent")) {
- ret += getString(R.string.careportal_newnstreatment_percent_label);
- ret += ": ";
- ret += data.get("percent");
- ret += " %\n";
- }
- if (data.has("absolute")) {
- ret += getString(R.string.careportal_newnstreatment_absolute_label);
- ret += ": ";
- ret += data.get("absolute");
- ret += " U/h\n";
- }
- if (data.has("preBolus")) {
- ret += getString(R.string.careportal_newnstreatment_carbtime_label);
- ret += ": ";
- ret += data.get("preBolus");
- ret += " min\n";
- }
- if (data.has("notes")) {
- ret += getString(R.string.careportal_newnstreatment_notes_label);
- ret += ": ";
- ret += data.get("notes");
- ret += "\n";
- }
- if (data.has("profile")) {
- ret += getString(R.string.careportal_newnstreatment_profile_label);
- ret += ": ";
- ret += data.get("profile");
- ret += "\n";
- }
- if (data.has("percentage")) {
- ret += getString(R.string.careportal_newnstreatment_percentage_label);
- ret += ": ";
- ret += data.get("percentage");
- ret += " %\n";
- }
- if (data.has("timeshift")) {
- ret += getString(R.string.careportal_newnstreatment_timeshift_label);
- ret += ": ";
- ret += data.get("timeshift");
- ret += " h\n";
- }
- if (data.has("targetBottom") && data.has("targetTop")) {
- ret += getString(R.string.target_range);
- ret += " ";
- ret += data.get("targetBottom");
- ret += " - ";
- ret += data.get("targetTop");
- ret += "\n";
- }
- if (data.has("created_at")) {
- ret += getString(R.string.careportal_newnstreatment_eventtime_label);
- ret += ": ";
- ret += eventTime.toLocaleString();
- ret += "\n";
- }
- if (data.has("enteredBy")) {
- ret += getString(R.string.careportal_newnstreatment_enteredby_title);
- ret += ": ";
- ret += data.get("enteredBy");
- ret += "\n";
- }
- } catch (JSONException e) {
- log.error("Unhandled exception", e);
+ if (data.has("eventType")) {
+ ret += MainApp.gs(R.string.careportal_newnstreatment_eventtype);
+ ret += ": ";
+ ret += Translator.translate(JsonHelper.safeGetString(data, "eventType", ""));
+ ret += "\n";
+ }
+ if (data.has("glucose")) {
+ ret += MainApp.gs(R.string.treatments_wizard_bg_label);
+ ret += ": ";
+ ret += JsonHelper.safeGetObject(data, "glucose", "");
+ ret += " " + units + "\n";
+ }
+ if (data.has("glucoseType")) {
+ ret += MainApp.gs(R.string.careportal_newnstreatment_glucosetype);
+ ret += ": ";
+ ret += Translator.translate(JsonHelper.safeGetString(data, "glucoseType", ""));
+ ret += "\n";
+ }
+ if (data.has("carbs")) {
+ ret += MainApp.gs(R.string.careportal_newnstreatment_carbs_label);
+ ret += ": ";
+ ret += JsonHelper.safeGetObject(data, "carbs", "");
+ ret += " g\n";
+ }
+ if (data.has("insulin")) {
+ ret += MainApp.gs(R.string.careportal_newnstreatment_insulin_label);
+ ret += ": ";
+ ret += JsonHelper.safeGetObject(data, "insulin", "");
+ ret += " U\n";
+ }
+ if (data.has("duration")) {
+ ret += MainApp.gs(R.string.careportal_newnstreatment_duration_label);
+ ret += ": ";
+ ret += JsonHelper.safeGetObject(data, "duration", "");
+ ret += " min\n";
+ }
+ if (data.has("percent")) {
+ ret += MainApp.gs(R.string.careportal_newnstreatment_percent_label);
+ ret += ": ";
+ ret += JsonHelper.safeGetObject(data, "percent", "");
+ ret += " %\n";
+ }
+ if (data.has("absolute")) {
+ ret += MainApp.gs(R.string.careportal_newnstreatment_absolute_label);
+ ret += ": ";
+ ret += JsonHelper.safeGetObject(data, "absolute", "");
+ ret += " U/h\n";
+ }
+ if (data.has("preBolus")) {
+ ret += MainApp.gs(R.string.careportal_newnstreatment_carbtime_label);
+ ret += ": ";
+ ret += JsonHelper.safeGetObject(data, "preBolus", "");
+ ret += " min\n";
+ }
+ if (data.has("notes")) {
+ ret += MainApp.gs(R.string.careportal_newnstreatment_notes_label);
+ ret += ": ";
+ ret += JsonHelper.safeGetObject(data, "notes", "");
+ ret += "\n";
+ }
+ if (data.has("profile")) {
+ ret += MainApp.gs(R.string.careportal_newnstreatment_profile_label);
+ ret += ": ";
+ ret += JsonHelper.safeGetObject(data, "profile", "");
+ ret += "\n";
+ }
+ if (data.has("percentage")) {
+ ret += MainApp.gs(R.string.careportal_newnstreatment_percentage_label);
+ ret += ": ";
+ ret += JsonHelper.safeGetObject(data, "percentage", "");
+ ret += " %\n";
+ }
+ if (data.has("timeshift")) {
+ ret += MainApp.gs(R.string.careportal_newnstreatment_timeshift_label);
+ ret += ": ";
+ ret += JsonHelper.safeGetObject(data, "timeshift", "");
+ ret += " h\n";
+ }
+ if (data.has("targetBottom") && data.has("targetTop")) {
+ ret += MainApp.gs(R.string.target_range);
+ ret += " ";
+ ret += JsonHelper.safeGetObject(data, "targetBottom", "");
+ ret += " - ";
+ ret += JsonHelper.safeGetObject(data, "targetTop", "");
+ ret += "\n";
+ }
+ if (data.has("created_at")) {
+ ret += MainApp.gs(R.string.careportal_newnstreatment_eventtime_label);
+ ret += ": ";
+ ret += eventTime.toLocaleString();
+ ret += "\n";
+ }
+ if (data.has("enteredBy")) {
+ ret += MainApp.gs(R.string.careportal_newnstreatment_enteredby_title);
+ ret += ": ";
+ ret += JsonHelper.safeGetObject(data, "enteredBy", "");
+ ret += "\n";
}
return ret;
}
- void createNSTreatment() {
- final JSONObject data = gatherData();
- String confirmText = buildConfirmText(data);
- AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
- builder.setTitle(getContext().getString(R.string.confirmation));
- builder.setMessage(confirmText);
- builder.setPositiveButton(getContext().getString(R.string.ok), new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int id) {
- if (options.executeProfileSwitch) {
- if (data.has("profile")) {
- try {
- doProfileSwitch(profileStore, data.getString("profile"), data.getInt("duration"), data.getInt("percentage"), data.getInt("timeshift"));
- } catch (JSONException e) {
- log.error("Unhandled exception", e);
- }
- }
- } else if (options.executeTempTarget) {
- try {
- if ((data.has("targetBottom") && data.has("targetTop")) || (data.has("duration") && data.getInt("duration") == 0)) {
- TempTarget tempTarget = new TempTarget()
- .date(eventTime.getTime())
- .duration(data.getInt("duration"))
- .reason(data.getString("reason"))
- .source(Source.USER);
- if (tempTarget.durationInMinutes != 0) {
- tempTarget.low(Profile.toMgdl(data.getDouble("targetBottom"), profile.getUnits()))
- .high(Profile.toMgdl(data.getDouble("targetTop"), profile.getUnits()));
- } else {
- tempTarget.low(0).high(0);
- }
- log.debug("Creating new TempTarget db record: " + tempTarget.toString());
- MainApp.getDbHelper().createOrUpdate(tempTarget);
- NSUpload.uploadCareportalEntryToNS(data);
- FabricPrivacy.getInstance().logCustom(new CustomEvent("TempTarget"));
- }
- } catch (JSONException e) {
- log.error("Unhandled exception", e);
- }
- } else {
- NSUpload.uploadCareportalEntryToNS(data);
- FabricPrivacy.getInstance().logCustom(new CustomEvent("NSTreatment"));
- }
+ void confirmNSTreatmentCreation() {
+ if (context != null) {
+ final JSONObject data = gatherData();
+ final String confirmText = buildConfirmText(data);
+ AlertDialog.Builder builder = new AlertDialog.Builder(context);
+ builder.setTitle(MainApp.gs(R.string.confirmation));
+ builder.setMessage(confirmText);
+ builder.setPositiveButton(MainApp.gs(R.string.ok), (dialog, id) -> createNSTreatment(data));
+ builder.setNegativeButton(MainApp.gs(R.string.cancel), null);
+ builder.show();
+ }
+ }
+
+
+ public void createNSTreatment(JSONObject data) {
+ if (options.executeProfileSwitch) {
+ if (data.has("profile")) {
+ doProfileSwitch(profileStore, JsonHelper.safeGetString(data, "profile"), JsonHelper.safeGetInt(data, "duration"), JsonHelper.safeGetInt(data, "percentage"), JsonHelper.safeGetInt(data, "timeshift"));
}
- });
- builder.setNegativeButton(getContext().getString(R.string.cancel), null);
- builder.show();
+ } else 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, profile.getUnits()))
+ .high(Profile.toMgdl(targetTop, profile.getUnits()));
+ } else {
+ tempTarget.low(0).high(0);
+ }
+ TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget);
+ FabricPrivacy.getInstance().logCustom(new CustomEvent("TempTarget"));
+ }
+ } else {
+ NSUpload.uploadCareportalEntryToNS(data);
+ FabricPrivacy.getInstance().logCustom(new CustomEvent("NSTreatment"));
+ }
}
public static void doProfileSwitch(final ProfileStore profileStore, final String profileName, final int duration, final int percentage, final int timeshift) {
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/ConfigBuilder/ConfigBuilderPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/ConfigBuilder/ConfigBuilderPlugin.java
index c6b2e3ce96..06ddbef86f 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/ConfigBuilder/ConfigBuilderPlugin.java
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/ConfigBuilder/ConfigBuilderPlugin.java
@@ -264,10 +264,6 @@ public class ConfigBuilderPlugin extends PluginBase {
return activeAPS;
}
- public static LoopPlugin getActiveLoop() {
- return activeLoop;
- }
-
public static PumpInterface getActivePump() {
return activePump;
}
@@ -621,7 +617,7 @@ public class ConfigBuilderPlugin extends PluginBase {
}
public void disconnectPump(int durationInMinutes, Profile profile) {
- getActiveLoop().disconnectTo(System.currentTimeMillis() + durationInMinutes * 60 * 1000L);
+ LoopPlugin.getPlugin().disconnectTo(System.currentTimeMillis() + durationInMinutes * 60 * 1000L);
getCommandQueue().tempBasalPercent(0, durationInMinutes, true, profile, new Callback() {
@Override
public void run() {
@@ -644,7 +640,7 @@ public class ConfigBuilderPlugin extends PluginBase {
}
public void suspendLoop(int durationInMinutes) {
- getActiveLoop().suspendTo(System.currentTimeMillis() + durationInMinutes * 60 * 1000);
+ LoopPlugin.getPlugin().suspendTo(System.currentTimeMillis() + durationInMinutes * 60 * 1000);
getCommandQueue().cancelTempBasal(true, new Callback() {
@Override
public void run() {
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsObjectives/ObjectivesFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsObjectives/ObjectivesFragment.java
index 23f5cb1fb8..688c741329 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsObjectives/ObjectivesFragment.java
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsObjectives/ObjectivesFragment.java
@@ -85,37 +85,52 @@ public class ObjectivesFragment extends SubscriberFragment {
}
});
- Long now = System.currentTimeMillis();
- if (position > 0 && objectives.get(position - 1).accomplished.getTime() == 0) {
- // Phase 0: previous not completed
- holder.startedLayout.setVisibility(View.GONE);
- holder.durationLayout.setVisibility(View.GONE);
- holder.progressLayout.setVisibility(View.GONE);
- holder.verifyLayout.setVisibility(View.GONE);
- } else if (o.started.getTime() == 0) {
- // Phase 1: not started
- holder.durationLayout.setVisibility(View.GONE);
- holder.progressLayout.setVisibility(View.GONE);
- holder.verifyLayout.setVisibility(View.GONE);
- holder.started.setVisibility(View.GONE);
- } else if (o.started.getTime() > 0 && !enableFake.isChecked() && o.accomplished.getTime() == 0 && !(o.started.getTime() + o.durationInDays * 24 * 60 * 60 * 1000 < now && requirementsMet.done)) {
- // Phase 2: started, waiting for duration and met requirements
- holder.startButton.setEnabled(false);
- holder.verifyLayout.setVisibility(View.GONE);
- } else if (o.accomplished.getTime() == 0) {
- // Phase 3: started, after duration, requirements met
- holder.startButton.setEnabled(false);
- holder.accomplished.setVisibility(View.INVISIBLE);
- } else {
- // Phase 4: verified
- holder.gateLayout.setVisibility(View.GONE);
- holder.startedLayout.setVisibility(View.GONE);
- holder.durationLayout.setVisibility(View.GONE);
- holder.progressLayout.setVisibility(View.GONE);
- holder.verifyButton.setVisibility(View.INVISIBLE);
+ long prevObjectiveAccomplishedTime = position > 0 ?
+ objectives.get(position - 1).accomplished.getTime() : -1;
+
+ int phase = modifyVisibility(position, prevObjectiveAccomplishedTime,
+ o.started.getTime(), o.durationInDays,
+ o.accomplished.getTime(), requirementsMet.done, enableFake.isChecked());
+
+ switch (phase) {
+ case 0:
+ // Phase 0: previous not completed
+ holder.startedLayout.setVisibility(View.GONE);
+ holder.durationLayout.setVisibility(View.GONE);
+ holder.progressLayout.setVisibility(View.GONE);
+ holder.verifyLayout.setVisibility(View.GONE);
+ break;
+ case 1:
+ // Phase 1: not started
+ holder.durationLayout.setVisibility(View.GONE);
+ holder.progressLayout.setVisibility(View.GONE);
+ holder.verifyLayout.setVisibility(View.GONE);
+ holder.started.setVisibility(View.GONE);
+ break;
+ case 2:
+ // Phase 2: started, waiting for duration and met requirements
+ holder.startButton.setEnabled(false);
+ holder.verifyLayout.setVisibility(View.GONE);
+ break;
+ case 3:
+ // Phase 3: started, after duration, requirements met
+ holder.startButton.setEnabled(false);
+ holder.accomplished.setVisibility(View.INVISIBLE);
+ break;
+ case 4:
+ // Phase 4: verified
+ holder.gateLayout.setVisibility(View.GONE);
+ holder.startedLayout.setVisibility(View.GONE);
+ holder.durationLayout.setVisibility(View.GONE);
+ holder.progressLayout.setVisibility(View.GONE);
+ holder.verifyButton.setVisibility(View.INVISIBLE);
+ break;
+ default:
+ // should not happen
}
}
+
@Override
public int getItemCount() {
return objectives.size();
@@ -164,6 +179,40 @@ public class ObjectivesFragment extends SubscriberFragment {
}
}
+ /**
+ * returns an int, which represents the phase the current objective is at.
+ *
+ * this is mainly used for unit-testing the conditions
+ *
+ * @param currentPosition
+ * @param prevObjectiveAccomplishedTime
+ * @param objectiveStartedTime
+ * @param durationInDays
+ * @param objectiveAccomplishedTime
+ * @param requirementsMet
+ * @return
+ */
+ public int modifyVisibility(int currentPosition,
+ long prevObjectiveAccomplishedTime,
+ long objectiveStartedTime, int durationInDays,
+ long objectiveAccomplishedTime, boolean requirementsMet,
+ boolean enableFakeValue) {
+ Long now = System.currentTimeMillis();
+ if (currentPosition > 0 && prevObjectiveAccomplishedTime == 0) {
+ return 0;
+ } else if (objectiveStartedTime == 0) {
+ return 1;
+ } else if (objectiveStartedTime > 0 && !enableFakeValue
+ && objectiveAccomplishedTime == 0
+ && !(objectiveStartedTime + durationInDays * 24 * 60 * 60 * 1000 >= now && requirementsMet)) {
+ return 2;
+ } else if (objectiveAccomplishedTime == 0) {
+ return 3;
+ } else {
+ return 4;
+ }
+ }
+
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
@@ -205,6 +254,7 @@ public class ObjectivesFragment extends SubscriberFragment {
ObjectivesPlugin.objectives.get(3).gate = MainApp.sResources.getString(R.string.objectives_3_gate);
ObjectivesPlugin.objectives.get(4).gate = MainApp.sResources.getString(R.string.objectives_4_gate);
ObjectivesPlugin.objectives.get(5).gate = MainApp.sResources.getString(R.string.objectives_5_gate);
+
updateGUI();
return view;
@@ -225,4 +275,4 @@ public class ObjectivesFragment extends SubscriberFragment {
});
}
-}
+}
\ No newline at end of file
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Loop/LoopPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/Loop/LoopPlugin.java
index e29eda04dc..e5510aae00 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/Loop/LoopPlugin.java
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/Loop/LoopPlugin.java
@@ -9,6 +9,7 @@ import android.app.TaskStackBuilder;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
+import android.support.annotation.NonNull;
import android.support.v4.app.NotificationCompat;
import com.crashlytics.android.answers.CustomEvent;
@@ -56,6 +57,7 @@ public class LoopPlugin extends PluginBase {
protected static LoopPlugin loopPlugin;
+ @NonNull
public static LoopPlugin getPlugin() {
if (loopPlugin == null) {
loopPlugin = new LoopPlugin();
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/NewCarbsDialog.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/NewCarbsDialog.java
index 19119450df..bd489971c2 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/NewCarbsDialog.java
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/NewCarbsDialog.java
@@ -1,15 +1,14 @@
package info.nightscout.androidaps.plugins.Overview.Dialogs;
-import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.HandlerThread;
+import android.support.annotation.Nullable;
import android.support.v4.app.DialogFragment;
import android.support.v7.app.AlertDialog;
import android.text.Editable;
import android.text.Html;
import android.text.TextWatcher;
-import android.text.format.DateFormat;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
@@ -18,20 +17,16 @@ import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.CompoundButton;
+import android.widget.EditText;
+import android.widget.LinearLayout;
import android.widget.RadioButton;
-import android.widget.TextView;
import com.google.common.base.Joiner;
-import com.wdullaer.materialdatetimepicker.date.DatePickerDialog;
-import com.wdullaer.materialdatetimepicker.time.RadialPickerLayout;
-import com.wdullaer.materialdatetimepicker.time.TimePickerDialog;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.text.DecimalFormat;
-import java.util.Calendar;
-import java.util.Date;
import java.util.LinkedList;
import java.util.List;
@@ -49,36 +44,32 @@ import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
import info.nightscout.androidaps.queue.Callback;
import info.nightscout.utils.DateUtil;
import info.nightscout.utils.DecimalFormatter;
+import info.nightscout.utils.DefaultValueHelper;
import info.nightscout.utils.NumberPicker;
import info.nightscout.utils.SP;
-import info.nightscout.utils.SafeParse;
import info.nightscout.utils.ToastUtils;
-public class NewCarbsDialog extends DialogFragment implements OnClickListener, DatePickerDialog.OnDateSetListener, TimePickerDialog.OnTimeSetListener, CompoundButton.OnCheckedChangeListener {
+import static info.nightscout.utils.DateUtil.now;
+
+public class NewCarbsDialog extends DialogFragment implements OnClickListener, CompoundButton.OnCheckedChangeListener {
private static Logger log = LoggerFactory.getLogger(NewCarbsDialog.class);
- private NumberPicker editCarbs;
-
- private TextView dateButton;
- private TextView timeButton;
-
- private Date initialEventTime;
- private Date eventTime;
-
- private Button fav1Button;
- private Button fav2Button;
- private Button fav3Button;
-
private static final int FAV1_DEFAULT = 5;
private static final int FAV2_DEFAULT = 10;
private static final int FAV3_DEFAULT = 20;
+
private RadioButton startActivityTTCheckbox;
private RadioButton startEatingSoonTTCheckbox;
private RadioButton startHypoTTCheckbox;
private boolean togglingTT;
+ private NumberPicker editTime;
+ private NumberPicker editDuration;
+ private NumberPicker editCarbs;
private Integer maxCarbs;
+ private EditText notesEdit;
+
//one shot guards
private boolean accepted;
private boolean okClicked;
@@ -91,6 +82,7 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, D
final private TextWatcher textWatcher = new TextWatcher() {
@Override
public void afterTextChanged(Editable s) {
+ validateInputs();
}
@Override
@@ -99,12 +91,21 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, D
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
- validateInputs();
}
};
private void validateInputs() {
- Integer carbs = SafeParse.stringToInt(editCarbs.getText());
+ int time = editTime.getValue().intValue();
+ if (time > 12 * 60 || time < -12 * 60) {
+ editTime.setValue(0d);
+ ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.constraintapllied));
+ }
+ Double duration = editDuration.getValue();
+ if (duration > 10) {
+ editDuration.setValue(0d);
+ ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.constraintapllied));
+ }
+ int carbs = editCarbs.getValue().intValue();
if (carbs > maxCarbs) {
editCarbs.setValue(0d);
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.carbsconstraintapplied));
@@ -122,12 +123,6 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, D
getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
- maxCarbs = MainApp.getConstraintChecker().getMaxCarbsAllowed().value();
-
- editCarbs = view.findViewById(R.id.newcarb_carbsamount);
-
- editCarbs.setParams(0d, 0d, (double) maxCarbs, 1d, new DecimalFormat("0"), false, textWatcher);
-
startActivityTTCheckbox = view.findViewById(R.id.newcarbs_activity_tt);
startActivityTTCheckbox.setOnCheckedChangeListener(this);
startEatingSoonTTCheckbox = view.findViewById(R.id.newcarbs_eating_soon_tt);
@@ -135,28 +130,36 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, D
startHypoTTCheckbox = view.findViewById(R.id.newcarbs_hypo_tt);
startHypoTTCheckbox.setOnCheckedChangeListener(this);
- dateButton = view.findViewById(R.id.newcarbs_eventdate);
- timeButton = view.findViewById(R.id.newcarb_eventtime);
+ editTime = view.findViewById(R.id.newcarbs_time);
+ editTime.setParams(0d, -12 * 60d, 12 * 60d, 5d, new DecimalFormat("0"), false, textWatcher);
- initialEventTime = new Date();
- eventTime = new Date(initialEventTime.getTime());
- dateButton.setText(DateUtil.dateString(eventTime));
- timeButton.setText(DateUtil.timeString(eventTime));
- dateButton.setOnClickListener(this);
- timeButton.setOnClickListener(this);
+ LinearLayout durationLayout = view.findViewById(R.id.newcarbs_duration_layout);
+ durationLayout.setVisibility(MainApp.engineeringMode ? View.VISIBLE : View.GONE);
- fav1Button = view.findViewById(R.id.newcarbs_plus1);
+ editDuration = view.findViewById(R.id.new_carbs_duration);
+ editDuration.setParams(0d, 0d, 10d, 1d, new DecimalFormat("0"), false, textWatcher);
+
+ maxCarbs = MainApp.getConstraintChecker().getMaxCarbsAllowed().value();
+
+ editCarbs = view.findViewById(R.id.newcarb_carbsamount);
+ editCarbs.setParams(0d, 0d, (double) maxCarbs, 1d, new DecimalFormat("0"), false, textWatcher);
+
+ Button fav1Button = view.findViewById(R.id.newcarbs_plus1);
fav1Button.setOnClickListener(this);
fav1Button.setText(toSignedString(SP.getInt(R.string.key_carbs_button_increment_1, FAV1_DEFAULT)));
- fav2Button = view.findViewById(R.id.newcarbs_plus2);
+ Button fav2Button = view.findViewById(R.id.newcarbs_plus2);
fav2Button.setOnClickListener(this);
fav2Button.setText(toSignedString(SP.getInt(R.string.key_carbs_button_increment_2, FAV2_DEFAULT)));
- fav3Button = view.findViewById(R.id.newcarbs_plus3);
+ Button fav3Button = view.findViewById(R.id.newcarbs_plus3);
fav3Button.setOnClickListener(this);
fav3Button.setText(toSignedString(SP.getInt(R.string.key_carbs_button_increment_3, FAV3_DEFAULT)));
+ LinearLayout notesLayout = view.findViewById(R.id.newcarbs_notes_layout);
+ notesLayout.setVisibility(SP.getBoolean(R.string.key_show_notes_entry_dialogs, false) ? View.VISIBLE : View.GONE);
+ notesEdit = view.findViewById(R.id.newcarbs_notes);
+
setCancelable(true);
getDialog().setCanceledOnTouchOutside(false);
return view;
@@ -168,8 +171,6 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, D
@Override
public synchronized void onClick(View view) {
- Calendar calendar = Calendar.getInstance();
- calendar.setTime(eventTime);
switch (view.getId()) {
case R.id.ok:
submit();
@@ -177,28 +178,6 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, D
case R.id.cancel:
dismiss();
break;
- case R.id.newcarbs_eventdate:
- DatePickerDialog dpd = DatePickerDialog.newInstance(
- this,
- calendar.get(Calendar.YEAR),
- calendar.get(Calendar.MONTH),
- calendar.get(Calendar.DAY_OF_MONTH)
- );
- dpd.setThemeDark(true);
- dpd.dismissOnPause(true);
- dpd.show(getActivity().getFragmentManager(), "Datepickerdialog");
- break;
- case R.id.newcarb_eventtime:
- TimePickerDialog tpd = TimePickerDialog.newInstance(
- this,
- calendar.get(Calendar.HOUR_OF_DAY),
- calendar.get(Calendar.MINUTE),
- DateFormat.is24HourFormat(getActivity())
- );
- tpd.setThemeDark(true);
- tpd.dismissOnPause(true);
- tpd.show(getActivity().getFragmentManager(), "Timepickerdialog");
- break;
case R.id.newcarbs_plus1:
editCarbs.setValue(Math.max(0, editCarbs.getValue()
+ SP.getInt(R.string.key_carbs_button_increment_1, FAV1_DEFAULT)));
@@ -304,39 +283,35 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, D
}
okClicked = true;
try {
- final Integer carbs = SafeParse.stringToInt(editCarbs.getText());
+ final Profile currentProfile = MainApp.getConfigBuilder().getProfile();
+ if (currentProfile == null) {
+ return;
+ }
+
+ int carbs = editCarbs.getValue().intValue();
Integer carbsAfterConstraints = MainApp.getConstraintChecker().applyCarbsConstraints(new Constraint<>(carbs)).value();
+ final String units = currentProfile.getUnits();
+ DefaultValueHelper helper = new DefaultValueHelper();
+
+ int activityTTDuration = helper.determineActivityTTDuration();
+ double activityTT = helper.determineActivityTT(units);
+
+ int eatingSoonTTDuration = helper.determineEatingSoonTTDuration();
+ double eatingSoonTT = helper.determineEatingSoonTT(units);
+
+ int hypoTTDuration = helper.determineHypoTTDuration();
+ double hypoTT = helper.determineHypoTT(units);
+
List actions = new LinkedList<>();
- if (carbs > 0)
- actions.add(MainApp.gs(R.string.carbs) + ": " + "" + carbsAfterConstraints + "g" + "");
- if (!carbsAfterConstraints.equals(carbs))
- actions.add("" + MainApp.gs(R.string.carbsconstraintapplied) + "");
-
- final Profile currentProfile = MainApp.getConfigBuilder().getProfile();
- if (currentProfile == null)
- return;
-
- int activityTTDuration = SP.getInt(R.string.key_activity_duration, Constants.defaultActivityTTDuration);
- activityTTDuration = activityTTDuration > 0 ? activityTTDuration : Constants.defaultActivityTTDuration;
- double activityTT = SP.getDouble(R.string.key_activity_target, currentProfile.getUnits().equals(Constants.MMOL) ? Constants.defaultActivityTTmmol : Constants.defaultActivityTTmgdl);
- activityTT = activityTT > 0 ? activityTT : currentProfile.getUnits().equals(Constants.MMOL) ? Constants.defaultActivityTTmmol : Constants.defaultActivityTTmgdl;
-
- int eatingSoonTTDuration = SP.getInt(R.string.key_eatingsoon_duration, Constants.defaultEatingSoonTTDuration);
- eatingSoonTTDuration = eatingSoonTTDuration > 0 ? eatingSoonTTDuration : Constants.defaultEatingSoonTTDuration;
- double eatingSoonTT = SP.getDouble(R.string.key_eatingsoon_target, currentProfile.getUnits().equals(Constants.MMOL) ? Constants.defaultEatingSoonTTmmol : Constants.defaultEatingSoonTTmgdl);
- eatingSoonTT = eatingSoonTT > 0 ? eatingSoonTT : currentProfile.getUnits().equals(Constants.MMOL) ? Constants.defaultEatingSoonTTmmol : Constants.defaultEatingSoonTTmgdl;
-
- int hypoTTDuration = SP.getInt(R.string.key_hypo_duration, Constants.defaultHypoTTDuration);
- hypoTTDuration = hypoTTDuration > 0 ? hypoTTDuration : Constants.defaultHypoTTDuration;
- double hypoTT = SP.getDouble(R.string.key_hypo_target, currentProfile.getUnits().equals(Constants.MMOL) ? Constants.defaultHypoTTmmol : Constants.defaultHypoTTmgdl);
- hypoTT = hypoTT > 0 ? hypoTT : currentProfile.getUnits().equals(Constants.MMOL) ? Constants.defaultHypoTTmmol : Constants.defaultHypoTTmgdl;
if (startActivityTTCheckbox.isChecked()) {
+ String unitLabel = "mg/dl";
if (currentProfile.getUnits().equals(Constants.MMOL)) {
- actions.add(MainApp.gs(R.string.temptargetshort) + ": " + "" + DecimalFormatter.to1Decimal(activityTT) + " mmol/l (" + activityTTDuration + " min)");
- } else
- actions.add(MainApp.gs(R.string.temptargetshort) + ": " + "" + DecimalFormatter.to0Decimal(activityTT) + " mg/dl (" + activityTTDuration + " min)");
+ unitLabel = "mmol/l";
+ }
+
+ actions.add(MainApp.gs(R.string.temptargetshort) + ": " + "" + DecimalFormatter.to1Decimal(activityTT) + " " + unitLabel + " (" + activityTTDuration + " min)");
}
if (startEatingSoonTTCheckbox.isChecked()) {
@@ -352,6 +327,26 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, D
actions.add(MainApp.gs(R.string.temptargetshort) + ": " + "" + DecimalFormatter.to0Decimal(hypoTT) + " mg/dl (" + hypoTTDuration + " min)");
}
+ int timeOffset = editTime.getValue().intValue();
+ final long time = now() + timeOffset * 1000 * 60;
+ if (timeOffset != 0) {
+ actions.add(MainApp.gs(R.string.time) + ": " + DateUtil.dateAndTimeString(time));
+ }
+ int duration = editDuration.getValue().intValue();
+ if (duration > 0) {
+ actions.add(MainApp.gs(R.string.duration) + ": " + duration + MainApp.gs(R.string.shorthour));
+ }
+ if (carbs > 0) {
+ actions.add(MainApp.gs(R.string.carbs) + ": " + "" + carbsAfterConstraints + "g" + "");
+ }
+ if (!carbsAfterConstraints.equals(carbs)) {
+ actions.add("" + MainApp.gs(R.string.carbsconstraintapplied) + "");
+ }
+ final String notes = notesEdit.getText().toString();
+ if (!notes.isEmpty()) {
+ actions.add(MainApp.gs(R.string.careportal_newnstreatment_notes_label) + ": " + notes);
+ }
+
final double finalActivityTT = activityTT;
final int finalActivityTTDuration = activityTTDuration;
final double finalEatigSoonTT = eatingSoonTT;
@@ -359,26 +354,18 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, D
final double finalHypoTT = hypoTT;
final int finalHypoTTDuration = hypoTTDuration;
- if (!initialEventTime.equals(eventTime)) {
- actions.add("Time: " + DateUtil.dateAndTimeString(eventTime));
- }
-
- final int finalCarbsAfterConstraints = carbsAfterConstraints;
-
- final Context context = getContext();
- final AlertDialog.Builder builder = new AlertDialog.Builder(context);
-
+ final AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setTitle(MainApp.gs(R.string.confirmation));
- builder.setMessage(actions.isEmpty()
- ? MainApp.gs(R.string.no_action_selected)
- : Html.fromHtml(Joiner.on("
").join(actions)));
- builder.setPositiveButton(MainApp.gs(R.string.ok), actions.isEmpty() ? null : (dialog, id) -> {
- synchronized (builder) {
- if (accepted) {
- log.debug("guarding: already accepted");
- return;
- }
- accepted = true;
+ if (carbsAfterConstraints > 0 || startActivityTTCheckbox.isChecked()
+ || startEatingSoonTTCheckbox.isChecked() || startHypoTTCheckbox.isChecked()) {
+ builder.setMessage(Html.fromHtml(Joiner.on("
").join(actions)));
+ builder.setPositiveButton(MainApp.gs(R.string.ok), (dialog, id) -> {
+ synchronized (builder) {
+ if (accepted) {
+ log.debug("guarding: already accepted");
+ return;
+ }
+ accepted = true;
if (startActivityTTCheckbox.isChecked()) {
TempTarget tempTarget = new TempTarget()
@@ -388,7 +375,7 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, D
.source(Source.USER)
.low(Profile.toMgdl(finalActivityTT, currentProfile.getUnits()))
.high(Profile.toMgdl(finalActivityTT, currentProfile.getUnits()));
- MainApp.getDbHelper().createOrUpdate(tempTarget);
+ TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget);
} else if (startEatingSoonTTCheckbox.isChecked()) {
TempTarget tempTarget = new TempTarget()
.date(System.currentTimeMillis())
@@ -397,7 +384,7 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, D
.source(Source.USER)
.low(Profile.toMgdl(finalEatigSoonTT, currentProfile.getUnits()))
.high(Profile.toMgdl(finalEatigSoonTT, currentProfile.getUnits()));
- MainApp.getDbHelper().createOrUpdate(tempTarget);
+ TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget);
} else if (startHypoTTCheckbox.isChecked()) {
TempTarget tempTarget = new TempTarget()
.date(System.currentTimeMillis())
@@ -406,36 +393,28 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, D
.source(Source.USER)
.low(Profile.toMgdl(finalHypoTT, currentProfile.getUnits()))
.high(Profile.toMgdl(finalHypoTT, currentProfile.getUnits()));
- MainApp.getDbHelper().createOrUpdate(tempTarget);
+ TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget);
}
- if (finalCarbsAfterConstraints > 0) {
- DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo();
- detailedBolusInfo.date = eventTime.getTime();
- detailedBolusInfo.eventType = CareportalEvent.CARBCORRECTION;
- detailedBolusInfo.carbs = finalCarbsAfterConstraints;
- detailedBolusInfo.context = context;
- detailedBolusInfo.source = Source.USER;
- if (ConfigBuilderPlugin.getActivePump().getPumpDescription().storesCarbInfo) {
- ConfigBuilderPlugin.getCommandQueue().bolus(detailedBolusInfo, new Callback() {
- @Override
- public void run() {
- if (!result.success) {
- Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class);
- i.putExtra("soundid", R.raw.boluserror);
- i.putExtra("status", result.comment);
- i.putExtra("title", MainApp.gs(R.string.treatmentdeliveryerror));
- i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- MainApp.instance().startActivity(i);
- }
+ if (carbsAfterConstraints > 0) {
+ if (duration == 0) {
+ createCarb(carbsAfterConstraints, time, notes);
+ } else {
+ long remainingCarbs = carbsAfterConstraints;
+ int ticks = (duration * 4); //duration guaranteed to be integer greater zero
+ for (int i = 0; i < ticks; i++){
+ long carbTime = time + i * 15 * 60 * 1000;
+ long smallCarbAmount = Math.round((1d * remainingCarbs) / (ticks-i)); //on last iteration (ticks-i) is 1 -> smallCarbAmount == remainingCarbs
+ remainingCarbs -= smallCarbAmount;
+ createCarb(smallCarbAmount, carbTime, notes);
}
- });
- } else {
- TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo);
+ }
}
}
- }
- });
+ });
+ } else {
+ builder.setMessage(MainApp.gs(R.string.no_action_selected));
+ }
builder.setNegativeButton(MainApp.gs(R.string.cancel), null);
builder.show();
dismiss();
@@ -444,19 +423,30 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, D
}
}
- @Override
- public void onDateSet(DatePickerDialog view, int year, int monthOfYear, int dayOfMonth) {
- eventTime.setYear(year - 1900);
- eventTime.setMonth(monthOfYear);
- eventTime.setDate(dayOfMonth);
- dateButton.setText(DateUtil.dateString(eventTime));
- }
-
- @Override
- public void onTimeSet(RadialPickerLayout view, int hourOfDay, int minute, int second) {
- eventTime.setHours(hourOfDay);
- eventTime.setMinutes(minute);
- eventTime.setSeconds(second);
- timeButton.setText(DateUtil.timeString(eventTime));
+ private void createCarb(long carbs, long time, @Nullable String notes) {
+ DetailedBolusInfo carbInfo = new DetailedBolusInfo();
+ carbInfo.date = time;
+ carbInfo.eventType = CareportalEvent.CARBCORRECTION;
+ carbInfo.carbs = carbs;
+ carbInfo.context = getContext();
+ carbInfo.source = Source.USER;
+ carbInfo.notes = notes;
+ if (ConfigBuilderPlugin.getActivePump().getPumpDescription().storesCarbInfo) {
+ ConfigBuilderPlugin.getCommandQueue().bolus(carbInfo, new Callback() {
+ @Override
+ public void run() {
+ if (!result.success) {
+ Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class);
+ i.putExtra("soundid", R.raw.boluserror);
+ i.putExtra("status", result.comment);
+ i.putExtra("title", MainApp.gs(R.string.treatmentdeliveryerror));
+ i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ MainApp.instance().startActivity(i);
+ }
+ }
+ });
+ } else {
+ TreatmentsPlugin.getPlugin().addToHistoryTreatment(carbInfo);
+ }
}
}
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/NewInsulinDialog.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/NewInsulinDialog.java
index ce19009cf8..3539bee093 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/NewInsulinDialog.java
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/NewInsulinDialog.java
@@ -9,7 +9,6 @@ import android.support.v7.app.AlertDialog;
import android.text.Editable;
import android.text.Html;
import android.text.TextWatcher;
-import android.text.format.DateFormat;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
@@ -18,19 +17,16 @@ import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.CheckBox;
-import android.widget.TextView;
+import android.widget.EditText;
+import android.widget.LinearLayout;
import com.crashlytics.android.answers.CustomEvent;
import com.google.common.base.Joiner;
-import com.wdullaer.materialdatetimepicker.date.DatePickerDialog;
-import com.wdullaer.materialdatetimepicker.time.RadialPickerLayout;
-import com.wdullaer.materialdatetimepicker.time.TimePickerDialog;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.util.Calendar;
-import java.util.Date;
+import java.text.DecimalFormat;
import java.util.LinkedList;
import java.util.List;
@@ -54,30 +50,25 @@ import info.nightscout.utils.SP;
import info.nightscout.utils.SafeParse;
import info.nightscout.utils.ToastUtils;
-public class NewInsulinDialog extends DialogFragment implements OnClickListener, DatePickerDialog.OnDateSetListener, TimePickerDialog.OnTimeSetListener {
+import static info.nightscout.utils.DateUtil.now;
+
+public class NewInsulinDialog extends DialogFragment implements OnClickListener {
private static Logger log = LoggerFactory.getLogger(NewInsulinDialog.class);
- private NumberPicker editInsulin;
-
- private TextView dateButton;
- private TextView timeButton;
-
- private Date initialEventTime;
- private Date eventTime;
-
- private Button plus1Button;
- private Button plus2Button;
- private Button plus3Button;
-
public static final double PLUS1_DEFAULT = 0.5d;
public static final double PLUS2_DEFAULT = 1d;
public static final double PLUS3_DEFAULT = 2d;
- private CheckBox startESMCheckbox;
+ private CheckBox startEatingSoonTTCheckbox;
private CheckBox recordOnlyCheckbox;
+ private LinearLayout editLayout;
+ private NumberPicker editTime;
+ private NumberPicker editInsulin;
private Double maxInsulin;
+ private EditText notesEdit;
+
//one shot guards
private boolean accepted;
private boolean okClicked;
@@ -90,6 +81,7 @@ public class NewInsulinDialog extends DialogFragment implements OnClickListener,
final private TextWatcher textWatcher = new TextWatcher() {
@Override
public void afterTextChanged(Editable s) {
+ validateInputs();
}
@Override
@@ -98,12 +90,16 @@ public class NewInsulinDialog extends DialogFragment implements OnClickListener,
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
- validateInputs();
}
};
private void validateInputs() {
- Double insulin = SafeParse.stringToDouble(editInsulin.getText());
+ int time = editTime.getValue().intValue();
+ if (Math.abs(time) > 12 * 60) {
+ editTime.setValue(0d);
+ ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.constraintapllied));
+ }
+ Double insulin = editInsulin.getValue();
if (insulin > maxInsulin) {
editInsulin.setValue(0d);
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.bolusconstraintapplied));
@@ -121,39 +117,34 @@ public class NewInsulinDialog extends DialogFragment implements OnClickListener,
getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
+ startEatingSoonTTCheckbox = view.findViewById(R.id.newinsulin_start_eating_soon_tt);
+
+ recordOnlyCheckbox = view.findViewById(R.id.newinsulin_record_only);
+ recordOnlyCheckbox.setOnCheckedChangeListener((buttonView, isChecked) -> editLayout.setVisibility(isChecked ? View.VISIBLE : View.GONE));
+
+ editLayout = view.findViewById(R.id.newinsulin_time_layout);
+ editLayout.setVisibility(View.GONE);
+ editTime = view.findViewById(R.id.newinsulin_time);
+ editTime.setParams(0d, -12 * 60d, 12 * 60d, 5d, new DecimalFormat("0"), false, textWatcher);
+
maxInsulin = MainApp.getConstraintChecker().getMaxBolusAllowed().value();
- editInsulin = (NumberPicker) view.findViewById(R.id.treatments_newinsulin_amount);
-
+ editInsulin = view.findViewById(R.id.newinsulin_amount);
editInsulin.setParams(0d, 0d, maxInsulin, ConfigBuilderPlugin.getActivePump().getPumpDescription().bolusStep, DecimalFormatter.pumpSupportedBolusFormat(), false, textWatcher);
- dateButton = (TextView) view.findViewById(R.id.newinsulin_eventdate);
- timeButton = (TextView) view.findViewById(R.id.newinsulin_eventtime);
-
- initialEventTime = new Date();
- eventTime = new Date(initialEventTime.getTime());
- dateButton.setText(DateUtil.dateString(eventTime));
- timeButton.setText(DateUtil.timeString(eventTime));
- dateButton.setOnClickListener(this);
- timeButton.setOnClickListener(this);
-
- plus1Button = (Button) view.findViewById(R.id.newinsulin_plus05);
+ Button plus1Button = view.findViewById(R.id.newinsulin_plus05);
plus1Button.setOnClickListener(this);
plus1Button.setText(toSignedString(SP.getDouble(MainApp.gs(R.string.key_insulin_button_increment_1), PLUS1_DEFAULT)));
- plus2Button = (Button) view.findViewById(R.id.newinsulin_plus10);
+ Button plus2Button = view.findViewById(R.id.newinsulin_plus10);
plus2Button.setOnClickListener(this);
plus2Button.setText(toSignedString(SP.getDouble(MainApp.gs(R.string.key_insulin_button_increment_2), PLUS2_DEFAULT)));
- plus3Button = (Button) view.findViewById(R.id.newinsulin_plus20);
+ Button plus3Button = view.findViewById(R.id.newinsulin_plus20);
plus3Button.setOnClickListener(this);
plus3Button.setText(toSignedString(SP.getDouble(MainApp.gs(R.string.key_insulin_button_increment_3), PLUS3_DEFAULT)));
- startESMCheckbox = (CheckBox) view.findViewById(R.id.newinsulin_start_eating_soon_tt);
-
- recordOnlyCheckbox = (CheckBox) view.findViewById(R.id.newinsulin_record_only);
- recordOnlyCheckbox.setOnCheckedChangeListener((buttonView, isChecked) -> {
- if (dateButton != null) dateButton.setEnabled(isChecked);
- if (timeButton != null) timeButton.setEnabled(isChecked);
- });
+ LinearLayout notesLayout = view.findViewById(R.id.newinsulin_notes_layout);
+ notesLayout.setVisibility(SP.getBoolean(R.string.key_show_notes_entry_dialogs, false) ? View.VISIBLE : View.GONE);
+ notesEdit = view.findViewById(R.id.newinsulin_notes);
setCancelable(true);
getDialog().setCanceledOnTouchOutside(false);
@@ -167,8 +158,6 @@ public class NewInsulinDialog extends DialogFragment implements OnClickListener,
@Override
public synchronized void onClick(View view) {
- Calendar calendar = Calendar.getInstance();
- calendar.setTime(eventTime);
switch (view.getId()) {
case R.id.ok:
submit();
@@ -176,28 +165,6 @@ public class NewInsulinDialog extends DialogFragment implements OnClickListener,
case R.id.cancel:
dismiss();
break;
- case R.id.newinsulin_eventdate:
- DatePickerDialog dpd = DatePickerDialog.newInstance(
- this,
- calendar.get(Calendar.YEAR),
- calendar.get(Calendar.MONTH),
- calendar.get(Calendar.DAY_OF_MONTH)
- );
- dpd.setThemeDark(true);
- dpd.dismissOnPause(true);
- dpd.show(getActivity().getFragmentManager(), "Datepickerdialog");
- break;
- case R.id.newinsulin_eventtime:
- TimePickerDialog tpd = TimePickerDialog.newInstance(
- this,
- calendar.get(Calendar.HOUR_OF_DAY),
- calendar.get(Calendar.MINUTE),
- DateFormat.is24HourFormat(getActivity())
- );
- tpd.setThemeDark(true);
- tpd.dismissOnPause(true);
- tpd.show(getActivity().getFragmentManager(), "Timepickerdialog");
- break;
case R.id.newinsulin_plus05:
editInsulin.setValue(Math.max(0, editInsulin.getValue()
+ SP.getDouble(MainApp.gs(R.string.key_insulin_button_increment_1), PLUS1_DEFAULT)));
@@ -225,6 +192,10 @@ public class NewInsulinDialog extends DialogFragment implements OnClickListener,
okClicked = true;
try {
+ Profile currentProfile = MainApp.getConfigBuilder().getProfile();
+ if (currentProfile == null)
+ return;
+
Double insulin = SafeParse.stringToDouble(editInsulin.getText());
Double insulinAfterConstraints = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(insulin)).value();
@@ -239,92 +210,90 @@ public class NewInsulinDialog extends DialogFragment implements OnClickListener,
if (!insulinAfterConstraints.equals(insulin))
actions.add("" + MainApp.gs(R.string.bolusconstraintapplied) + "");
- double prefTTDuration = SP.getDouble(R.string.key_eatingsoon_duration, 45d);
- double ttDuration = prefTTDuration > 0 ? prefTTDuration : 45d;
- double prefTT = SP.getDouble(R.string.key_eatingsoon_target, 80d);
- Profile currentProfile = MainApp.getConfigBuilder().getProfile();
- if (currentProfile == null)
- return;
- double tt;
- if (currentProfile.getUnits().equals(Constants.MMOL))
- tt = prefTT > 0 ? Profile.toMgdl(prefTT, Constants.MMOL) : 80d;
- else
- tt = prefTT > 0 ? prefTT : 80d;
- final double finalTT = tt;
+ int eatingSoonTTDuration = SP.getInt(R.string.key_eatingsoon_duration, Constants.defaultEatingSoonTTDuration);
+ eatingSoonTTDuration = eatingSoonTTDuration > 0 ? eatingSoonTTDuration : Constants.defaultEatingSoonTTDuration;
+ double eatingSoonTT = SP.getDouble(R.string.key_eatingsoon_target, currentProfile.getUnits().equals(Constants.MMOL) ? Constants.defaultEatingSoonTTmmol : Constants.defaultEatingSoonTTmgdl);
+ eatingSoonTT = eatingSoonTT > 0 ? eatingSoonTT : currentProfile.getUnits().equals(Constants.MMOL) ? Constants.defaultEatingSoonTTmmol : Constants.defaultEatingSoonTTmgdl;
- if (startESMCheckbox.isChecked()) {
- if (currentProfile.getUnits().equals("mmol")) {
- actions.add("TT: " + "" + Profile.toMmol(tt, Constants.MGDL) + " mmol for " + ((int) ttDuration) + " min ");
+ if (startEatingSoonTTCheckbox.isChecked()) {
+ if (currentProfile.getUnits().equals(Constants.MMOL)) {
+ actions.add(MainApp.gs(R.string.temptargetshort) + ": " + "" + DecimalFormatter.to1Decimal(eatingSoonTT) + " mmol/l (" + eatingSoonTTDuration + " min)");
} else
- actions.add("TT: " + "" + ((int) tt) + "mg/dl for " + ((int) ttDuration) + " min ");
+ actions.add(MainApp.gs(R.string.temptargetshort) + ": " + "" + DecimalFormatter.to0Decimal(eatingSoonTT) + " mg/dl (" + eatingSoonTTDuration + " min)");
}
- if (!initialEventTime.equals(eventTime)) {
- actions.add("Time: " + DateUtil.dateAndTimeString(eventTime));
+ int timeOffset = editTime.getValue().intValue();
+ final long time = now() + timeOffset * 1000 * 60;
+ if (timeOffset != 0) {
+ actions.add(MainApp.gs(R.string.time) + ": " + DateUtil.dateAndTimeString(time));
+ }
+ final String notes = notesEdit.getText().toString();
+ if (!notes.isEmpty()) {
+ actions.add(MainApp.gs(R.string.careportal_newnstreatment_notes_label) + ": " + notes);
}
final double finalInsulinAfterConstraints = insulinAfterConstraints;
+ final double finalEatigSoonTT = eatingSoonTT;
+ final int finalEatingSoonTTDuration = eatingSoonTTDuration;
final Context context = getContext();
final AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(MainApp.gs(R.string.confirmation));
- builder.setMessage(actions.isEmpty()
- ? MainApp.gs(R.string.no_action_selected)
- : Html.fromHtml(Joiner.on("
").join(actions)));
- builder.setPositiveButton(MainApp.gs(R.string.ok), actions.isEmpty() ? null : (dialog, id) -> {
- synchronized (builder) {
- if (accepted) {
- log.debug("guarding: already accepted");
- return;
- }
- accepted = true;
+ if (finalInsulinAfterConstraints > 0 || startEatingSoonTTCheckbox.isChecked()) {
+ builder.setMessage(Html.fromHtml(Joiner.on("
").join(actions)));
+ builder.setPositiveButton(MainApp.gs(R.string.ok), (dialog, id) -> {
+ synchronized (builder) {
+ if (accepted) {
+ log.debug("guarding: already accepted");
+ return;
+ }
+ accepted = true;
- if (startESMCheckbox.isChecked()) {
- TempTarget tempTarget = new TempTarget()
- .date(System.currentTimeMillis())
- .duration((int) ttDuration)
- .reason("Eating soon")
- .source(Source.USER)
- .low((int) finalTT)
- .high((int) finalTT);
- MainApp.getDbHelper().createOrUpdate(tempTarget);
- }
+ if (startEatingSoonTTCheckbox.isChecked()) {
+ TempTarget tempTarget = new TempTarget()
+ .date(System.currentTimeMillis())
+ .duration(finalEatingSoonTTDuration)
+ .reason(MainApp.gs(R.string.eatingsoon))
+ .source(Source.USER)
+ .low(Profile.toMgdl(finalEatigSoonTT, currentProfile.getUnits()))
+ .high(Profile.toMgdl(finalEatigSoonTT, currentProfile.getUnits()));
+ TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget);
+ }
- if (finalInsulinAfterConstraints <= 0.01) {
- return;
- }
-
- if (recordOnlyCheckbox.isChecked()) {
- DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo();
- detailedBolusInfo.source = Source.USER;
- detailedBolusInfo.date = eventTime.getTime();
- detailedBolusInfo.eventType = CareportalEvent.CORRECTIONBOLUS;
- detailedBolusInfo.insulin = finalInsulinAfterConstraints;
- TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo);
- } else {
- DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo();
- detailedBolusInfo.eventType = CareportalEvent.CORRECTIONBOLUS;
- detailedBolusInfo.insulin = finalInsulinAfterConstraints;
- detailedBolusInfo.context = context;
- detailedBolusInfo.source = Source.USER;
- ConfigBuilderPlugin.getCommandQueue().bolus(detailedBolusInfo, new Callback() {
- @Override
- public void run() {
- if (!result.success) {
- Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class);
- i.putExtra("soundid", R.raw.boluserror);
- i.putExtra("status", result.comment);
- i.putExtra("title", MainApp.gs(R.string.treatmentdeliveryerror));
- i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- MainApp.instance().startActivity(i);
- }
+ if (finalInsulinAfterConstraints > 0) {
+ DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo();
+ detailedBolusInfo.eventType = CareportalEvent.CORRECTIONBOLUS;
+ detailedBolusInfo.insulin = finalInsulinAfterConstraints;
+ detailedBolusInfo.context = context;
+ detailedBolusInfo.source = Source.USER;
+ detailedBolusInfo.notes = notes;
+ if (recordOnlyCheckbox.isChecked()) {
+ detailedBolusInfo.date = time;
+ TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo);
+ } else {
+ detailedBolusInfo.date = now();
+ ConfigBuilderPlugin.getCommandQueue().bolus(detailedBolusInfo, new Callback() {
+ @Override
+ public void run() {
+ if (!result.success) {
+ Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class);
+ i.putExtra("soundid", R.raw.boluserror);
+ i.putExtra("status", result.comment);
+ i.putExtra("title", MainApp.gs(R.string.treatmentdeliveryerror));
+ i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ MainApp.instance().startActivity(i);
+ }
+ }
+ });
+ FabricPrivacy.getInstance().logCustom(new CustomEvent("Bolus"));
}
- });
- FabricPrivacy.getInstance().logCustom(new CustomEvent("Bolus"));
+ }
}
- }
- });
+ });
+ } else {
+ builder.setMessage(MainApp.gs(R.string.no_action_selected));
+ }
builder.setNegativeButton(MainApp.gs(R.string.cancel), null);
builder.show();
dismiss();
@@ -332,20 +301,4 @@ public class NewInsulinDialog extends DialogFragment implements OnClickListener,
log.error("Unhandled exception", e);
}
}
-
- @Override
- public void onDateSet(DatePickerDialog view, int year, int monthOfYear, int dayOfMonth) {
- eventTime.setYear(year - 1900);
- eventTime.setMonth(monthOfYear);
- eventTime.setDate(dayOfMonth);
- dateButton.setText(DateUtil.dateString(eventTime));
- }
-
- @Override
- public void onTimeSet(RadialPickerLayout view, int hourOfDay, int minute, int second) {
- eventTime.setHours(hourOfDay);
- eventTime.setMinutes(minute);
- eventTime.setSeconds(second);
- timeButton.setText(DateUtil.timeString(eventTime));
- }
}
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/WizardDialog.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/WizardDialog.java
index f44e570774..edee0c838d 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/WizardDialog.java
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/WizardDialog.java
@@ -21,6 +21,7 @@ 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;
@@ -53,6 +54,7 @@ import info.nightscout.androidaps.events.EventFeatureRunning;
import info.nightscout.androidaps.events.EventNewBG;
import info.nightscout.androidaps.events.EventRefreshOverview;
import info.nightscout.androidaps.interfaces.Constraint;
+import info.nightscout.androidaps.interfaces.PluginType;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.IobCobCalculator.AutosensData;
import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin;
@@ -103,6 +105,9 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
NumberPicker editCorr;
NumberPicker editCarbTime;
+ LinearLayout notesLayout;
+ EditText notesEdit;
+
Integer calculatedCarbs = 0;
Double calculatedTotalInsulin = 0d;
JSONObject boluscalcJSON;
@@ -205,6 +210,10 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
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);
@@ -320,6 +329,7 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
final Double bg = SafeParse.stringToDouble(editBg.getText());
final int carbTime = SafeParse.stringToInt(editCarbTime.getText());
final boolean useSuperBolus = superbolusCheckbox.isChecked();
+ final String finalNotes = notesEdit.getText().toString();
final AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(MainApp.sResources.getString(R.string.confirmation));
@@ -334,9 +344,9 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
accepted = true;
if (finalInsulinAfterConstraints > 0 || finalCarbsAfterConstraints > 0) {
if (useSuperBolus) {
- final LoopPlugin activeloop = ConfigBuilderPlugin.getActiveLoop();
- if (activeloop != null) {
- activeloop.superBolusTo(System.currentTimeMillis() + 2 * 60L * 60 * 1000);
+ final LoopPlugin loopPlugin = LoopPlugin.getPlugin();
+ if (loopPlugin.isEnabled(PluginType.LOOP)) {
+ loopPlugin.superBolusTo(System.currentTimeMillis() + 2 * 60L * 60 * 1000);
MainApp.bus().post(new EventRefreshOverview("WizardDialog"));
}
ConfigBuilderPlugin.getCommandQueue().tempBasalPercent(0, 120, true, profile, new Callback() {
@@ -363,6 +373,7 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
detailedBolusInfo.carbTime = carbTime;
detailedBolusInfo.boluscalc = boluscalcJSON;
detailedBolusInfo.source = Source.USER;
+ detailedBolusInfo.notes = finalNotes;
if (detailedBolusInfo.insulin > 0 || ConfigBuilderPlugin.getActivePump().getPumpDescription().storesCarbInfo) {
ConfigBuilderPlugin.getCommandQueue().bolus(detailedBolusInfo, new Callback() {
@Override
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/OverviewFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/OverviewFragment.java
index d6c9c70c4e..b22d0450e0 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/OverviewFragment.java
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/OverviewFragment.java
@@ -79,6 +79,7 @@ import info.nightscout.androidaps.events.EventCareportalEventChange;
import info.nightscout.androidaps.events.EventExtendedBolusChange;
import info.nightscout.androidaps.events.EventInitializationChanged;
import info.nightscout.androidaps.events.EventPreferenceChange;
+import info.nightscout.androidaps.events.EventProfileSwitchChange;
import info.nightscout.androidaps.events.EventPumpStatusChanged;
import info.nightscout.androidaps.events.EventRefreshOverview;
import info.nightscout.androidaps.events.EventTempBasalChange;
@@ -457,14 +458,14 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
if (v == apsModeView) {
- final LoopPlugin activeloop = ConfigBuilderPlugin.getActiveLoop();
+ final LoopPlugin loopPlugin = LoopPlugin.getPlugin();
final PumpDescription pumpDescription = ConfigBuilderPlugin.getActivePump().getPumpDescription();
- if (activeloop == null || !MainApp.getConfigBuilder().isProfileValid("ContexMenuCreation"))
+ if (loopPlugin == null || !MainApp.getConfigBuilder().isProfileValid("ContexMenuCreation"))
return;
menu.setHeaderTitle(MainApp.gs(R.string.loop));
- if (activeloop.isEnabled(PluginType.LOOP)) {
+ if (loopPlugin.isEnabled(PluginType.LOOP)) {
menu.add(MainApp.gs(R.string.disableloop));
- if (!activeloop.isSuspended()) {
+ if (!loopPlugin.isSuspended()) {
menu.add(MainApp.gs(R.string.suspendloopfor1h));
menu.add(MainApp.gs(R.string.suspendloopfor2h));
menu.add(MainApp.gs(R.string.suspendloopfor3h));
@@ -480,7 +481,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
menu.add(MainApp.gs(R.string.resume));
}
}
- if (!activeloop.isEnabled(PluginType.LOOP))
+ if (!loopPlugin.isEnabled(PluginType.LOOP))
menu.add(MainApp.gs(R.string.enableloop));
} else if (v == activeProfileView) {
menu.setHeaderTitle(MainApp.gs(R.string.profile));
@@ -496,13 +497,13 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
final Profile profile = MainApp.getConfigBuilder().getProfile();
if (profile == null)
return true;
- final LoopPlugin activeloop = ConfigBuilderPlugin.getActiveLoop();
+ final LoopPlugin loopPlugin = LoopPlugin.getPlugin();
if (item.getTitle().equals(MainApp.gs(R.string.disableloop))) {
- activeloop.setPluginEnabled(PluginType.LOOP, false);
- activeloop.setFragmentVisible(PluginType.LOOP, false);
+ loopPlugin.setPluginEnabled(PluginType.LOOP, false);
+ loopPlugin.setFragmentVisible(PluginType.LOOP, false);
MainApp.getConfigBuilder().storeSettings("DisablingLoop");
updateGUI("suspendmenu");
- MainApp.getConfigBuilder().getCommandQueue().cancelTempBasal(true, new Callback() {
+ ConfigBuilderPlugin.getCommandQueue().cancelTempBasal(true, new Callback() {
@Override
public void run() {
if (!result.success) {
@@ -513,16 +514,16 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
NSUpload.uploadOpenAPSOffline(24 * 60); // upload 24h, we don't know real duration
return true;
} else if (item.getTitle().equals(MainApp.gs(R.string.enableloop))) {
- activeloop.setPluginEnabled(PluginType.LOOP, true);
- activeloop.setFragmentVisible(PluginType.LOOP, true);
+ loopPlugin.setPluginEnabled(PluginType.LOOP, true);
+ loopPlugin.setFragmentVisible(PluginType.LOOP, true);
MainApp.getConfigBuilder().storeSettings("EnablingLoop");
updateGUI("suspendmenu");
NSUpload.uploadOpenAPSOffline(0);
return true;
} else if (item.getTitle().equals(MainApp.gs(R.string.resume))) {
- activeloop.suspendTo(0L);
+ loopPlugin.suspendTo(0L);
updateGUI("suspendmenu");
- MainApp.getConfigBuilder().getCommandQueue().cancelTempBasal(true, new Callback() {
+ ConfigBuilderPlugin.getCommandQueue().cancelTempBasal(true, new Callback() {
@Override
public void run() {
if (!result.success) {
@@ -673,36 +674,34 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
private void onClickAcceptTemp() {
Profile profile = MainApp.getConfigBuilder().getProfile();
- if (ConfigBuilderPlugin.getActiveLoop() != null && profile != null) {
- ConfigBuilderPlugin.getActiveLoop().invoke("Accept temp button", false);
+ if (LoopPlugin.getPlugin().isEnabled(PluginType.LOOP) && profile != null) {
+ LoopPlugin.getPlugin().invoke("Accept temp button", false);
final LoopPlugin.LastRun finalLastRun = LoopPlugin.lastRun;
if (finalLastRun != null && finalLastRun.lastAPSRun != null && finalLastRun.constraintsProcessed.isChangeRequested()) {
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setTitle(getContext().getString(R.string.confirmation));
builder.setMessage(getContext().getString(R.string.setbasalquestion) + "\n" + finalLastRun.constraintsProcessed);
- builder.setPositiveButton(getContext().getString(R.string.ok), new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int id) {
- hideTempRecommendation();
- clearNotification();
- MainApp.getConfigBuilder().applyTBRRequest(finalLastRun.constraintsProcessed, profile, new Callback() {
- @Override
- public void run() {
- if (result.enacted) {
- finalLastRun.tbrSetByPump = result;
- finalLastRun.lastEnact = new Date();
- finalLastRun.lastOpenModeAccept = new Date();
- NSUpload.uploadDeviceStatus();
- ObjectivesPlugin objectivesPlugin = MainApp.getSpecificPlugin(ObjectivesPlugin.class);
- if (objectivesPlugin != null) {
- ObjectivesPlugin.manualEnacts++;
- ObjectivesPlugin.saveProgress();
- }
+ builder.setPositiveButton(getContext().getString(R.string.ok), (dialog, id) -> {
+ hideTempRecommendation();
+ clearNotification();
+ MainApp.getConfigBuilder().applyTBRRequest(finalLastRun.constraintsProcessed, profile, new Callback() {
+ @Override
+ public void run() {
+ if (result.enacted) {
+ finalLastRun.tbrSetByPump = result;
+ finalLastRun.lastEnact = new Date();
+ finalLastRun.lastOpenModeAccept = new Date();
+ NSUpload.uploadDeviceStatus();
+ ObjectivesPlugin objectivesPlugin = MainApp.getSpecificPlugin(ObjectivesPlugin.class);
+ if (objectivesPlugin != null) {
+ ObjectivesPlugin.manualEnacts++;
+ ObjectivesPlugin.saveProgress();
}
- scheduleUpdateGUI("onClickAcceptTemp");
}
- });
- FabricPrivacy.getInstance().logCustom(new CustomEvent("AcceptTemp"));
- }
+ scheduleUpdateGUI("onClickAcceptTemp");
+ }
+ });
+ FabricPrivacy.getInstance().logCustom(new CustomEvent("AcceptTemp"));
});
builder.setNegativeButton(getContext().getString(R.string.cancel), null);
builder.show();
@@ -768,57 +767,55 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
accepted = false;
builder.setTitle(MainApp.gs(R.string.confirmation));
builder.setMessage(confirmMessage);
- builder.setPositiveButton(getString(R.string.ok), new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int id) {
- synchronized (builder) {
- if (accepted) {
- log.debug("guarding: already accepted");
- return;
- }
- accepted = true;
- if (finalInsulinAfterConstraints > 0 || finalCarbsAfterConstraints > 0) {
- if (wizard.superBolus) {
- final LoopPlugin activeloop = ConfigBuilderPlugin.getActiveLoop();
- if (activeloop != null) {
- activeloop.superBolusTo(System.currentTimeMillis() + 2 * 60L * 60 * 1000);
- MainApp.bus().post(new EventRefreshOverview("WizardDialog"));
- }
- ConfigBuilderPlugin.getCommandQueue().tempBasalPercent(0, 120, true, profile, new Callback() {
- @Override
- public void run() {
- if (!result.success) {
- Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class);
- i.putExtra("soundid", R.raw.boluserror);
- i.putExtra("status", result.comment);
- i.putExtra("title", MainApp.gs(R.string.tempbasaldeliveryerror));
- i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- MainApp.instance().startActivity(i);
- }
- }
- });
+ builder.setPositiveButton(getString(R.string.ok), (dialog, id) -> {
+ synchronized (builder) {
+ if (accepted) {
+ log.debug("guarding: already accepted");
+ return;
+ }
+ accepted = true;
+ if (finalInsulinAfterConstraints > 0 || finalCarbsAfterConstraints > 0) {
+ if (wizard.superBolus) {
+ final LoopPlugin loopPlugin = LoopPlugin.getPlugin();
+ if (loopPlugin.isEnabled(PluginType.LOOP)) {
+ loopPlugin.superBolusTo(System.currentTimeMillis() + 2 * 60L * 60 * 1000);
+ MainApp.bus().post(new EventRefreshOverview("WizardDialog"));
}
- DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo();
- detailedBolusInfo.eventType = CareportalEvent.BOLUSWIZARD;
- detailedBolusInfo.insulin = finalInsulinAfterConstraints;
- detailedBolusInfo.carbs = finalCarbsAfterConstraints;
- detailedBolusInfo.context = context;
- detailedBolusInfo.boluscalc = boluscalcJSON;
- detailedBolusInfo.source = Source.USER;
- ConfigBuilderPlugin.getCommandQueue().bolus(detailedBolusInfo, new Callback() {
+ ConfigBuilderPlugin.getCommandQueue().tempBasalPercent(0, 120, true, profile, new Callback() {
@Override
public void run() {
if (!result.success) {
Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class);
i.putExtra("soundid", R.raw.boluserror);
i.putExtra("status", result.comment);
- i.putExtra("title", MainApp.gs(R.string.treatmentdeliveryerror));
+ i.putExtra("title", MainApp.gs(R.string.tempbasaldeliveryerror));
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
MainApp.instance().startActivity(i);
}
}
});
- FabricPrivacy.getInstance().logCustom(new CustomEvent("QuickWizard"));
}
+ DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo();
+ detailedBolusInfo.eventType = CareportalEvent.BOLUSWIZARD;
+ detailedBolusInfo.insulin = finalInsulinAfterConstraints;
+ detailedBolusInfo.carbs = finalCarbsAfterConstraints;
+ detailedBolusInfo.context = context;
+ detailedBolusInfo.boluscalc = boluscalcJSON;
+ detailedBolusInfo.source = Source.USER;
+ ConfigBuilderPlugin.getCommandQueue().bolus(detailedBolusInfo, new Callback() {
+ @Override
+ public void run() {
+ if (!result.success) {
+ Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class);
+ i.putExtra("soundid", R.raw.boluserror);
+ i.putExtra("status", result.comment);
+ i.putExtra("title", MainApp.gs(R.string.treatmentdeliveryerror));
+ i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ MainApp.instance().startActivity(i);
+ }
+ }
+ });
+ FabricPrivacy.getInstance().logCustom(new CustomEvent("QuickWizard"));
}
}
});
@@ -902,6 +899,11 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
scheduleUpdateGUI("EventTempTargetChange");
}
+ @Subscribe
+ public void onStatusEvent(final EventProfileSwitchChange ev) {
+ scheduleUpdateGUI("EventProfileSwitchChange");
+ }
+
@Subscribe
public void onStatusEvent(final EventPumpStatusChanged s) {
Activity activity = getActivity();
@@ -1024,24 +1026,24 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
apsModeView.setVisibility(View.VISIBLE);
apsModeView.setBackgroundColor(MainApp.sResources.getColor(R.color.loopenabled));
apsModeView.setTextColor(Color.BLACK);
- final LoopPlugin activeloop = ConfigBuilderPlugin.getActiveLoop();
- if (activeloop != null && activeloop.isEnabled(activeloop.getType()) && activeloop.isSuperBolus()) {
+ final LoopPlugin loopPlugin = LoopPlugin.getPlugin();
+ if (loopPlugin.isEnabled(PluginType.LOOP) && loopPlugin.isSuperBolus()) {
apsModeView.setBackgroundColor(MainApp.sResources.getColor(R.color.looppumpsuspended));
- apsModeView.setText(String.format(MainApp.gs(R.string.loopsuperbolusfor), activeloop.minutesToEndOfSuspend()));
+ apsModeView.setText(String.format(MainApp.gs(R.string.loopsuperbolusfor), loopPlugin.minutesToEndOfSuspend()));
apsModeView.setTextColor(Color.WHITE);
- } else if (activeloop != null && activeloop.isEnabled(activeloop.getType()) && activeloop.isDisconnected()) {
+ } else if (loopPlugin.isEnabled(PluginType.LOOP) && loopPlugin.isDisconnected()) {
apsModeView.setBackgroundColor(MainApp.sResources.getColor(R.color.looppumpsuspended));
- apsModeView.setText(String.format(MainApp.gs(R.string.loopdisconnectedfor), activeloop.minutesToEndOfSuspend()));
+ apsModeView.setText(String.format(MainApp.gs(R.string.loopdisconnectedfor), loopPlugin.minutesToEndOfSuspend()));
apsModeView.setTextColor(Color.WHITE);
- } else if (activeloop != null && activeloop.isEnabled(activeloop.getType()) && activeloop.isSuspended()) {
+ } else if (loopPlugin.isEnabled(PluginType.LOOP) && loopPlugin.isSuspended()) {
apsModeView.setBackgroundColor(MainApp.sResources.getColor(R.color.looppumpsuspended));
- apsModeView.setText(String.format(MainApp.gs(R.string.loopsuspendedfor), activeloop.minutesToEndOfSuspend()));
+ apsModeView.setText(String.format(MainApp.gs(R.string.loopsuspendedfor), loopPlugin.minutesToEndOfSuspend()));
apsModeView.setTextColor(Color.WHITE);
} else if (pump.isSuspended()) {
apsModeView.setBackgroundColor(MainApp.sResources.getColor(R.color.looppumpsuspended));
apsModeView.setText(MainApp.gs(R.string.pumpsuspended));
apsModeView.setTextColor(Color.WHITE);
- } else if (activeloop != null && activeloop.isEnabled(activeloop.getType())) {
+ } else if (loopPlugin.isEnabled(PluginType.LOOP)) {
if (closedLoopEnabled.value()) {
apsModeView.setText(MainApp.gs(R.string.closedloop));
} else {
@@ -1077,7 +1079,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
showAcceptButton = showAcceptButton && (finalLastRun.lastOpenModeAccept == null || finalLastRun.lastOpenModeAccept.getTime() < finalLastRun.lastAPSRun.getTime()); // never accepted or before last result
showAcceptButton = showAcceptButton && finalLastRun.constraintsProcessed.isChangeRequested(); // change is requested
- if (showAcceptButton && pump.isInitialized() && !pump.isSuspended() && ConfigBuilderPlugin.getActiveLoop() != null) {
+ if (showAcceptButton && pump.isInitialized() && !pump.isSuspended() && LoopPlugin.getPlugin().isEnabled(PluginType.LOOP)) {
acceptTempLayout.setVisibility(View.VISIBLE);
acceptTempButton.setText(getContext().getString(R.string.setbasalquestion) + "\n" + finalLastRun.constraintsProcessed);
} else {
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/graphData/GraphData.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/graphData/GraphData.java
index 1a8816d0b3..9921d236a1 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/graphData/GraphData.java
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/graphData/GraphData.java
@@ -172,7 +172,7 @@ public class GraphData {
lastAbsoluteLineBasal = absoluteLineValue;
lastLineBasal = baseBasalValue;
lastTempBasal = tempBasalValue;
- maxBasalValueFound = Math.max(maxBasalValueFound, basal);
+ maxBasalValueFound = Math.max(maxBasalValueFound, Math.max(tempBasalValue, baseBasalValue));
}
basalLineArray.add(new ScaledDataPoint(toTime, lastLineBasal, basalScale));
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 30e0d9b064..ce190b691b 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
@@ -1,7 +1,5 @@
package info.nightscout.androidaps.plugins.ProfileLocal;
-import android.content.SharedPreferences;
-import android.preference.PreferenceManager;
import android.support.annotation.NonNull;
import org.json.JSONArray;
@@ -70,18 +68,15 @@ public class LocalProfilePlugin extends PluginBase implements ProfileInterface {
}
public synchronized void storeSettings() {
- SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(MainApp.instance().getApplicationContext());
- SharedPreferences.Editor editor = settings.edit();
- editor.putBoolean(LOCAL_PROFILE + "mmol", mmol);
- editor.putBoolean(LOCAL_PROFILE + "mgdl", mgdl);
- editor.putString(LOCAL_PROFILE + "dia", dia.toString());
- editor.putString(LOCAL_PROFILE + "ic", ic.toString());
- editor.putString(LOCAL_PROFILE + "isf", isf.toString());
- editor.putString(LOCAL_PROFILE + "basal", basal.toString());
- editor.putString(LOCAL_PROFILE + "targetlow", targetLow.toString());
- editor.putString(LOCAL_PROFILE + "targethigh", targetHigh.toString());
+ SP.putBoolean(LOCAL_PROFILE + "mmol", mmol);
+ SP.putBoolean(LOCAL_PROFILE + "mgdl", mgdl);
+ SP.putString(LOCAL_PROFILE + "dia", dia.toString());
+ SP.putString(LOCAL_PROFILE + "ic", ic.toString());
+ SP.putString(LOCAL_PROFILE + "isf", isf.toString());
+ SP.putString(LOCAL_PROFILE + "basal", basal.toString());
+ SP.putString(LOCAL_PROFILE + "targetlow", targetLow.toString());
+ SP.putString(LOCAL_PROFILE + "targethigh", targetHigh.toString());
- editor.apply();
createAndStoreConvertedProfile();
edited = false;
if (Config.logPrefsChange)
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/SmsCommunicator/SmsCommunicatorPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/SmsCommunicator/SmsCommunicatorPlugin.java
index 8308a2eb92..a0192a528c 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/SmsCommunicator/SmsCommunicatorPlugin.java
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/SmsCommunicator/SmsCommunicatorPlugin.java
@@ -279,8 +279,7 @@ public class SmsCommunicatorPlugin extends PluginBase {
FabricPrivacy.getInstance().logCustom(new CustomEvent("SMS_Loop_Status"));
break;
case "RESUME":
- final LoopPlugin activeloop = ConfigBuilderPlugin.getActiveLoop();
- activeloop.suspendTo(0);
+ LoopPlugin.getPlugin().suspendTo(0);
MainApp.bus().post(new EventRefreshOverview("SMS_LOOP_RESUME"));
NSUpload.uploadOpenAPSOffline(0);
reply = MainApp.sResources.getString(R.string.smscommunicator_loopresumed);
@@ -517,8 +516,7 @@ public class SmsCommunicatorPlugin extends PluginBase {
@Override
public void run() {
if (result.success) {
- final LoopPlugin activeloop = ConfigBuilderPlugin.getActiveLoop();
- activeloop.suspendTo(System.currentTimeMillis() + suspendWaitingForConfirmation.duration * 60L * 1000);
+ LoopPlugin.getPlugin().suspendTo(System.currentTimeMillis() + suspendWaitingForConfirmation.duration * 60L * 1000);
NSUpload.uploadOpenAPSOffline(suspendWaitingForConfirmation.duration * 60);
MainApp.bus().post(new EventRefreshOverview("SMS_LOOP_SUSPENDED"));
String reply = MainApp.sResources.getString(R.string.smscommunicator_loopsuspended) + " " +
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Source/SourceXdripPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/Source/SourceXdripPlugin.java
index 0d33f529b3..f47d25abb1 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/Source/SourceXdripPlugin.java
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/Source/SourceXdripPlugin.java
@@ -12,6 +12,8 @@ import info.nightscout.androidaps.interfaces.PluginType;
public class SourceXdripPlugin extends PluginBase implements BgSourceInterface {
private static SourceXdripPlugin plugin = null;
+
+ boolean advancedFiltering;
public static SourceXdripPlugin getPlugin() {
if (plugin == null)
@@ -29,6 +31,10 @@ public class SourceXdripPlugin extends PluginBase implements BgSourceInterface {
@Override
public boolean advancedFilteringSupported() {
- return false;
+ return advancedFiltering;
+ }
+
+ public void setSource(String source) {
+ this.advancedFiltering = "G5 Native".equals(source);
}
}
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/TreatmentsPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/TreatmentsPlugin.java
index 36fac67834..8f82f71c35 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/TreatmentsPlugin.java
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/TreatmentsPlugin.java
@@ -452,7 +452,7 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
//log.debug("Adding new Treatment record" + carbsTreatment);
}
if (newRecordCreated && detailedBolusInfo.isValid)
- NSUpload.uploadBolusWizardRecord(detailedBolusInfo);
+ NSUpload.uploadTreatmentRecord(detailedBolusInfo);
return newRecordCreated;
}
@@ -505,6 +505,13 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
}
}
+ @Override
+ public void addToHistoryTempTarget(TempTarget tempTarget) {
+ //log.debug("Adding new TemporaryBasal record" + profileSwitch.log());
+ MainApp.getDbHelper().createOrUpdate(tempTarget);
+ NSUpload.uploadTempTarget(tempTarget);
+ }
+
// Profile Switch
@Subscribe
@SuppressWarnings("unused")
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsBolusFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsBolusFragment.java
index 87626ed4cd..ae977d4024 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsBolusFragment.java
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsBolusFragment.java
@@ -89,6 +89,10 @@ public class TreatmentsBolusFragment extends SubscriberFragment implements View.
holder.iob.setTextColor(ContextCompat.getColor(MainApp.instance(), R.color.colorActive));
else
holder.iob.setTextColor(holder.carbs.getCurrentTextColor());
+ if (t.date > DateUtil.now())
+ holder.date.setTextColor(ContextCompat.getColor(MainApp.instance(), R.color.colorScheduled));
+ else
+ holder.date.setTextColor(holder.carbs.getCurrentTextColor());
holder.remove.setTag(t);
}
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsTempTargetFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsTempTargetFragment.java
index d018efd97b..5ce79636b5 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsTempTargetFragment.java
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsTempTargetFragment.java
@@ -84,14 +84,10 @@ public class TreatmentsTempTargetFragment extends SubscriberFragment implements
holder.reasonLabel.setText("");
holder.reasonColon.setText("");
}
- if (tempTarget.isInProgress()) {
- if (tempTarget == currentlyActiveTarget) {
- // active as newest
- holder.date.setTextColor(ContextCompat.getColor(MainApp.instance(), R.color.colorInProgress));
- } else {
- // other's that might become active again after the latest (overlapping) is over
- holder.date.setTextColor(ContextCompat.getColor(MainApp.instance(), R.color.colorActive));
- }
+ if (tempTarget.isInProgress() && tempTarget == currentlyActiveTarget) {
+ holder.date.setTextColor(ContextCompat.getColor(MainApp.instance(), R.color.colorActive));
+ } else if (tempTarget.date > DateUtil.now()) {
+ holder.date.setTextColor(ContextCompat.getColor(MainApp.instance(), R.color.colorScheduled));
} else {
holder.date.setTextColor(holder.reasonColon.getCurrentTextColor());
}
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Wear/ActionStringHandler.java b/app/src/main/java/info/nightscout/androidaps/plugins/Wear/ActionStringHandler.java
index 48969d3dce..fdc14f32d4 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/Wear/ActionStringHandler.java
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/Wear/ActionStringHandler.java
@@ -441,21 +441,21 @@ public class ActionStringHandler {
private static String getLoopStatus() {
String ret = "";
// decide if enabled/disabled closed/open; what Plugin as APS?
- final LoopPlugin activeloop = MainApp.getConfigBuilder().getActiveLoop();
- if (activeloop != null && activeloop.isEnabled(activeloop.getType())) {
+ final LoopPlugin loopPlugin = LoopPlugin.getPlugin();
+ if (loopPlugin.isEnabled(loopPlugin.getType())) {
if (MainApp.getConstraintChecker().isClosedLoopAllowed().value()) {
ret += "CLOSED LOOP\n";
} else {
ret += "OPEN LOOP\n";
}
- final APSInterface aps = MainApp.getConfigBuilder().getActiveAPS();
+ final APSInterface aps = ConfigBuilderPlugin.getActiveAPS();
ret += "APS: " + ((aps == null) ? "NO APS SELECTED!" : ((PluginBase) aps).getName());
- if (activeloop.lastRun != null) {
- if (activeloop.lastRun.lastAPSRun != null)
- ret += "\nLast Run: " + DateUtil.timeString(activeloop.lastRun.lastAPSRun);
+ if (LoopPlugin.lastRun != null) {
+ if (LoopPlugin.lastRun.lastAPSRun != null)
+ ret += "\nLast Run: " + DateUtil.timeString(LoopPlugin.lastRun.lastAPSRun);
- if (activeloop.lastRun.lastEnact != null)
- ret += "\nLast Enact: " + DateUtil.timeString(activeloop.lastRun.lastEnact);
+ if (LoopPlugin.lastRun.lastEnact != null)
+ ret += "\nLast Enact: " + DateUtil.timeString(LoopPlugin.lastRun.lastEnact);
}
@@ -502,7 +502,7 @@ public class ActionStringHandler {
return "No profile set :(";
}
- APSInterface usedAPS = MainApp.getConfigBuilder().getActiveAPS();
+ APSInterface usedAPS = ConfigBuilderPlugin.getActiveAPS();
if (usedAPS == null) {
return "No active APS :(!";
}
@@ -622,10 +622,7 @@ public class ActionStringHandler {
} else {
tempTarget.low(0).high(0);
}
- MainApp.getDbHelper().createOrUpdate(tempTarget);
-
- //TODO: Nightscout-Treatment for Temp-Target!
- //ConfigBuilderPlugin.uploadCareportalEntryToNS(data);
+ TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget);
}
private static void doFillBolus(final Double amount) {
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Wear/WearPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/Wear/WearPlugin.java
index 668ec3f829..dcda0bc0aa 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/Wear/WearPlugin.java
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/Wear/WearPlugin.java
@@ -140,11 +140,7 @@ public class WearPlugin extends PluginBase {
@Subscribe
public void onStatusEvent(final EventRefreshOverview ev) {
-
- LoopPlugin activeloop = MainApp.getConfigBuilder().getActiveLoop();
- if (activeloop == null) return;
-
- if (WatchUpdaterService.shouldReportLoopStatus(activeloop.isEnabled(PluginType.LOOP))) {
+ if (WatchUpdaterService.shouldReportLoopStatus(LoopPlugin.getPlugin().isEnabled(PluginType.LOOP))) {
sendDataToWatch(true, false, false);
}
}
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Wear/wearintegration/WatchUpdaterService.java b/app/src/main/java/info/nightscout/androidaps/plugins/Wear/wearintegration/WatchUpdaterService.java
index bde197b45f..a92738d336 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/Wear/wearintegration/WatchUpdaterService.java
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/Wear/wearintegration/WatchUpdaterService.java
@@ -666,12 +666,12 @@ public class WatchUpdaterService extends WearableListenerService implements
return status;
}
- LoopPlugin activeloop = MainApp.getConfigBuilder().getActiveLoop();
+ LoopPlugin activeloop = LoopPlugin.getPlugin();
- if (activeloop != null && !activeloop.isEnabled(PluginType.LOOP)) {
+ if (!activeloop.isEnabled(PluginType.LOOP)) {
status += getString(R.string.disabledloop) + "\n";
lastLoopStatus = false;
- } else if (activeloop != null && activeloop.isEnabled(PluginType.LOOP)) {
+ } else {
lastLoopStatus = true;
}
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/XDripStatusline/StatuslinePlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/XDripStatusline/StatuslinePlugin.java
index b6b3c07e34..5ce277e399 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/XDripStatusline/StatuslinePlugin.java
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/XDripStatusline/StatuslinePlugin.java
@@ -108,12 +108,12 @@ public class StatuslinePlugin extends PluginBase {
@NonNull
private String buildStatusString(Profile profile) {
String status = "";
- LoopPlugin activeloop = ConfigBuilderPlugin.getActiveLoop();
+ LoopPlugin loopPlugin = LoopPlugin.getPlugin();
- if (activeloop != null && !activeloop.isEnabled(PluginType.LOOP)) {
+ if (!loopPlugin.isEnabled(PluginType.LOOP)) {
status += ctx.getString(R.string.disabledloop) + "\n";
lastLoopStatus = false;
- } else if (activeloop != null && activeloop.isEnabled(PluginType.LOOP)) {
+ } else if (loopPlugin.isEnabled(PluginType.LOOP)) {
lastLoopStatus = true;
}
@@ -179,13 +179,8 @@ public class StatuslinePlugin extends PluginBase {
@Subscribe
public void onStatusEvent(final EventRefreshOverview ev) {
-
//Filter events where loop is (de)activated
-
- LoopPlugin activeloop = ConfigBuilderPlugin.getActiveLoop();
- if (activeloop == null) return;
-
- if ((lastLoopStatus != activeloop.isEnabled(PluginType.LOOP))) {
+ if ((lastLoopStatus != LoopPlugin.getPlugin().isEnabled(PluginType.LOOP))) {
sendStatus();
}
}
diff --git a/app/src/main/java/info/nightscout/androidaps/queue/CommandQueue.java b/app/src/main/java/info/nightscout/androidaps/queue/CommandQueue.java
index fa15ee46d2..a514a85815 100644
--- a/app/src/main/java/info/nightscout/androidaps/queue/CommandQueue.java
+++ b/app/src/main/java/info/nightscout/androidaps/queue/CommandQueue.java
@@ -166,14 +166,19 @@ public class CommandQueue {
public boolean bolus(DetailedBolusInfo detailedBolusInfo, Callback callback) {
Command.CommandType type = detailedBolusInfo.isSMB ? Command.CommandType.SMB_BOLUS : Command.CommandType.BOLUS;
- if (isRunning(type)) {
- if (callback != null)
- callback.result(executingNowError()).run();
- return false;
- }
+ if(type.equals(Command.CommandType.BOLUS) && detailedBolusInfo.carbs > 0 && detailedBolusInfo.insulin == 0){
+ type = Command.CommandType.CARBS_ONLY_TREATMENT;
+ //Carbs only can be added in parallel as they can be "in the future".
+ } else {
+ if (isRunning(type)) {
+ if (callback != null)
+ callback.result(executingNowError()).run();
+ return false;
+ }
- // remove all unfinished boluses
- removeAll(type);
+ // remove all unfinished boluses
+ removeAll(type);
+ }
// apply constraints
detailedBolusInfo.insulin = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(detailedBolusInfo.insulin)).value();
@@ -183,12 +188,14 @@ public class CommandQueue {
if (detailedBolusInfo.isSMB) {
add(new CommandSMBBolus(detailedBolusInfo, callback));
} else {
- add(new CommandBolus(detailedBolusInfo, callback));
- // Bring up bolus progress dialog (start here, so the dialog is shown when the bolus is requested,
- // not when the Bolus command is starting. The command closes the dialog upon completion).
- showBolusProgressDialog(detailedBolusInfo.insulin, detailedBolusInfo.context);
- // Notify Wear about upcoming bolus
- MainApp.bus().post(new EventBolusRequested(detailedBolusInfo.insulin));
+ add(new CommandBolus(detailedBolusInfo, callback, type));
+ if(type.equals(Command.CommandType.BOLUS)) {
+ // Bring up bolus progress dialog (start here, so the dialog is shown when the bolus is requested,
+ // not when the Bolus command is starting. The command closes the dialog upon completion).
+ showBolusProgressDialog(detailedBolusInfo.insulin, detailedBolusInfo.context);
+ // Notify Wear about upcoming bolus
+ MainApp.bus().post(new EventBolusRequested(detailedBolusInfo.insulin));
+ }
}
notifyAboutNewCommand();
diff --git a/app/src/main/java/info/nightscout/androidaps/queue/QueueThread.java b/app/src/main/java/info/nightscout/androidaps/queue/QueueThread.java
index f9e0739b45..8ec61932c8 100644
--- a/app/src/main/java/info/nightscout/androidaps/queue/QueueThread.java
+++ b/app/src/main/java/info/nightscout/androidaps/queue/QueueThread.java
@@ -53,6 +53,12 @@ public class QueueThread extends Thread {
try {
while (true) {
PumpInterface pump = ConfigBuilderPlugin.getActivePump();
+ if (pump == null) {
+ log.debug("QUEUE: pump == null");
+ MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.pumpNotInitialized)));
+ SystemClock.sleep(1000);
+ continue;
+ }
long secondsElapsed = (System.currentTimeMillis() - connectionStartTime) / 1000;
if (!pump.isConnected() && secondsElapsed > Constants.PUMP_MAX_CONNECTION_TIME_IN_SECONDS) {
diff --git a/app/src/main/java/info/nightscout/androidaps/queue/commands/Command.java b/app/src/main/java/info/nightscout/androidaps/queue/commands/Command.java
index c5b3ada417..b865fac86e 100644
--- a/app/src/main/java/info/nightscout/androidaps/queue/commands/Command.java
+++ b/app/src/main/java/info/nightscout/androidaps/queue/commands/Command.java
@@ -12,6 +12,7 @@ public abstract class Command {
public enum CommandType {
BOLUS,
SMB_BOLUS,
+ CARBS_ONLY_TREATMENT,
TEMPBASAL,
EXTENDEDBOLUS,
BASALPROFILE,
diff --git a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandBolus.java b/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandBolus.java
index 278fd7681b..cab7d23311 100644
--- a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandBolus.java
+++ b/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandBolus.java
@@ -16,8 +16,8 @@ import info.nightscout.utils.DecimalFormatter;
public class CommandBolus extends Command {
DetailedBolusInfo detailedBolusInfo;
- public CommandBolus(DetailedBolusInfo detailedBolusInfo, Callback callback) {
- commandType = CommandType.BOLUS;
+ public CommandBolus(DetailedBolusInfo detailedBolusInfo, Callback callback, CommandType type) {
+ commandType = type;
this.detailedBolusInfo = detailedBolusInfo;
this.callback = callback;
}
diff --git a/app/src/main/java/info/nightscout/androidaps/startupwizard/SWDefinition.java b/app/src/main/java/info/nightscout/androidaps/startupwizard/SWDefinition.java
new file mode 100644
index 0000000000..e12a987bd1
--- /dev/null
+++ b/app/src/main/java/info/nightscout/androidaps/startupwizard/SWDefinition.java
@@ -0,0 +1,46 @@
+package info.nightscout.androidaps.startupwizard;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import info.nightscout.androidaps.R;
+import info.nightscout.androidaps.plugins.NSClientInternal.NSClientPlugin;
+import info.nightscout.utils.SP;
+
+public class SWDefinition {
+
+ private static SWDefinition swDefinition = null;
+
+ public static SWDefinition getInstance() {
+ if (swDefinition == null)
+ swDefinition = new SWDefinition();
+ return swDefinition;
+ }
+
+ static List screens = new ArrayList<>();
+
+ public static List getScreens() {
+ return screens;
+ }
+
+ SWDefinition add(SWScreen newScreen) {
+ screens.add(newScreen);
+ return this;
+ }
+
+ SWDefinition() {
+ add(new SWScreen(R.string.nsclientinternal_title)
+ .skippable(false)
+ .add(new SWUrl().preferenceId(R.string.key_nsclientinternal_url).label(R.string.nsclientinternal_url_title).comment(R.string.nsclientinternal_url_dialogmessage))
+ .add(new SWString().preferenceId(R.string.key_nsclientinternal_api_secret).label(R.string.nsclientinternal_secret_dialogtitle).comment(R.string.nsclientinternal_secret_dialogmessage))
+ .validator(() -> NSClientPlugin.getPlugin().nsClientService.isConnected && NSClientPlugin.getPlugin().nsClientService.hasWriteAuth)
+ )
+ .add(new SWScreen(R.string.patientage)
+ .skippable(false)
+ .add(new SWRadioButton().option(R.array.ageArray, R.array.ageValues).preferenceId(R.string.key_age).label(R.string.patientage).comment(R.string.patientage_summary))
+ .validator(() -> SP.contains(R.string.key_age))
+ )
+ ;
+ }
+
+}
diff --git a/app/src/main/java/info/nightscout/androidaps/startupwizard/SWItem.java b/app/src/main/java/info/nightscout/androidaps/startupwizard/SWItem.java
new file mode 100644
index 0000000000..4e41b4c0c7
--- /dev/null
+++ b/app/src/main/java/info/nightscout/androidaps/startupwizard/SWItem.java
@@ -0,0 +1,62 @@
+package info.nightscout.androidaps.startupwizard;
+
+import info.nightscout.androidaps.MainApp;
+import info.nightscout.androidaps.events.EventPreferenceChange;
+import info.nightscout.utils.SP;
+
+public class SWItem {
+ enum Type {
+ NONE,
+ URL,
+ STRING,
+ NUMBER,
+ DECIMALNUMBER,
+ CHECKBOX,
+ RADIOBUTTON
+ }
+
+ Type type;
+ Integer label;
+ Integer comment;
+ int preferenceId;
+
+
+ public SWItem(Type type) {
+ this.type = type;
+ }
+
+ String getLabel() {
+ return MainApp.gs(label);
+ }
+
+ String getComment() {
+ if (comment != null)
+ return MainApp.gs(comment);
+ else
+ return "";
+ }
+
+ Type getType() {
+ return type;
+ }
+
+ public SWItem label(int label) {
+ this.label = label;
+ return this;
+ }
+
+ public SWItem comment(int comment) {
+ this.comment = comment;
+ return this;
+ }
+
+ SWItem preferenceId(int preferenceId) {
+ this.preferenceId = preferenceId;
+ return this;
+ }
+
+ public void save(String value) {
+ SP.putString(preferenceId, value);
+ MainApp.bus().post(new EventPreferenceChange(preferenceId));
+ }
+}
diff --git a/app/src/main/java/info/nightscout/androidaps/startupwizard/SWRadioButton.java b/app/src/main/java/info/nightscout/androidaps/startupwizard/SWRadioButton.java
new file mode 100644
index 0000000000..5dc5c74438
--- /dev/null
+++ b/app/src/main/java/info/nightscout/androidaps/startupwizard/SWRadioButton.java
@@ -0,0 +1,28 @@
+package info.nightscout.androidaps.startupwizard;
+
+import info.nightscout.androidaps.MainApp;
+
+public class SWRadioButton extends SWItem {
+
+ int labelsArray;
+ int valuesArray;
+
+ public SWRadioButton() {
+ super(Type.RADIOBUTTON);
+ }
+
+ public SWRadioButton option(int labels, int values) {
+ this.labelsArray = labels;
+ this.valuesArray = values;
+ return this;
+ }
+
+ public String[] labels() {
+ return MainApp.sResources.getStringArray(labelsArray);
+ }
+
+ public String[] values() {
+ return MainApp.sResources.getStringArray(valuesArray);
+ }
+
+}
diff --git a/app/src/main/java/info/nightscout/androidaps/startupwizard/SWScreen.java b/app/src/main/java/info/nightscout/androidaps/startupwizard/SWScreen.java
new file mode 100644
index 0000000000..7ae674406d
--- /dev/null
+++ b/app/src/main/java/info/nightscout/androidaps/startupwizard/SWScreen.java
@@ -0,0 +1,43 @@
+package info.nightscout.androidaps.startupwizard;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import info.nightscout.androidaps.MainApp;
+
+public class SWScreen {
+
+ int header;
+ List items = new ArrayList<>();
+ SWValidator validator;
+ boolean skippable = false;
+
+ public SWScreen(int header) {
+ this.header = header;
+ }
+
+ public String getHeader() {
+ return MainApp.gs(header);
+ }
+
+ public SWScreen skippable(boolean skippable) {
+ this.skippable = skippable;
+ return this;
+ }
+
+ public SWScreen add(SWItem newItem) {
+ items.add(newItem);
+ return this;
+ }
+
+ public SWScreen validator(SWValidator validator) {
+ this.validator = validator;
+ return this;
+ }
+
+ boolean isValid() {
+ if (validator != null)
+ return validator.isValid();
+ return true;
+ }
+}
diff --git a/app/src/main/java/info/nightscout/androidaps/startupwizard/SWString.java b/app/src/main/java/info/nightscout/androidaps/startupwizard/SWString.java
new file mode 100644
index 0000000000..1378ca8e0f
--- /dev/null
+++ b/app/src/main/java/info/nightscout/androidaps/startupwizard/SWString.java
@@ -0,0 +1,8 @@
+package info.nightscout.androidaps.startupwizard;
+
+public class SWString extends SWItem {
+
+ public SWString() {
+ super(Type.STRING);
+ }
+}
diff --git a/app/src/main/java/info/nightscout/androidaps/startupwizard/SWUrl.java b/app/src/main/java/info/nightscout/androidaps/startupwizard/SWUrl.java
new file mode 100644
index 0000000000..d9ad6076ca
--- /dev/null
+++ b/app/src/main/java/info/nightscout/androidaps/startupwizard/SWUrl.java
@@ -0,0 +1,8 @@
+package info.nightscout.androidaps.startupwizard;
+
+public class SWUrl extends SWItem {
+
+ public SWUrl() {
+ super(Type.URL);
+ }
+}
diff --git a/app/src/main/java/info/nightscout/androidaps/startupwizard/SWValidator.java b/app/src/main/java/info/nightscout/androidaps/startupwizard/SWValidator.java
new file mode 100644
index 0000000000..e1fce21478
--- /dev/null
+++ b/app/src/main/java/info/nightscout/androidaps/startupwizard/SWValidator.java
@@ -0,0 +1,5 @@
+package info.nightscout.androidaps.startupwizard;
+
+public interface SWValidator {
+ boolean isValid();
+}
diff --git a/app/src/main/java/info/nightscout/androidaps/startupwizard/SetupWizardActivity.java b/app/src/main/java/info/nightscout/androidaps/startupwizard/SetupWizardActivity.java
new file mode 100644
index 0000000000..3fa9cd1501
--- /dev/null
+++ b/app/src/main/java/info/nightscout/androidaps/startupwizard/SetupWizardActivity.java
@@ -0,0 +1,165 @@
+package info.nightscout.androidaps.startupwizard;
+
+import android.annotation.SuppressLint;
+import android.support.v7.app.ActionBar;
+import android.support.v7.app.AppCompatActivity;
+import android.os.Bundle;
+import android.os.Handler;
+import android.view.MotionEvent;
+import android.view.View;
+
+import info.nightscout.androidaps.R;
+
+/**
+ * An example full-screen activity that shows and hides the system UI (i.e.
+ * status bar and navigation/system bar) with user interaction.
+ */
+public class SetupWizardActivity extends AppCompatActivity {
+ /**
+ * Whether or not the system UI should be auto-hidden after
+ * {@link #AUTO_HIDE_DELAY_MILLIS} milliseconds.
+ */
+ private static final boolean AUTO_HIDE = true;
+
+ /**
+ * If {@link #AUTO_HIDE} is set, the number of milliseconds to wait after
+ * user interaction before hiding the system UI.
+ */
+ private static final int AUTO_HIDE_DELAY_MILLIS = 3000;
+
+ /**
+ * Some older devices needs a small delay between UI widget updates
+ * and a change of the status and navigation bar.
+ */
+ private static final int UI_ANIMATION_DELAY = 300;
+ private final Handler mHideHandler = new Handler();
+ private View mContentView;
+ private final Runnable mHidePart2Runnable = new Runnable() {
+ @SuppressLint("InlinedApi")
+ @Override
+ public void run() {
+ // Delayed removal of status and navigation bar
+
+ // Note that some of these constants are new as of API 16 (Jelly Bean)
+ // and API 19 (KitKat). It is safe to use them, as they are inlined
+ // at compile-time and do nothing on earlier devices.
+ mContentView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE
+ | View.SYSTEM_UI_FLAG_FULLSCREEN
+ | View.SYSTEM_UI_FLAG_LAYOUT_STABLE
+ | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
+ | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
+ | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
+ }
+ };
+ private View mControlsView;
+ private final Runnable mShowPart2Runnable = new Runnable() {
+ @Override
+ public void run() {
+ // Delayed display of UI elements
+ ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.show();
+ }
+ mControlsView.setVisibility(View.VISIBLE);
+ }
+ };
+ private boolean mVisible;
+ private final Runnable mHideRunnable = new Runnable() {
+ @Override
+ public void run() {
+ hide();
+ }
+ };
+ /**
+ * Touch listener to use for in-layout UI controls to delay hiding the
+ * system UI. This is to prevent the jarring behavior of controls going away
+ * while interacting with activity UI.
+ */
+ private final View.OnTouchListener mDelayHideTouchListener = new View.OnTouchListener() {
+ @Override
+ public boolean onTouch(View view, MotionEvent motionEvent) {
+ if (AUTO_HIDE) {
+ delayedHide(AUTO_HIDE_DELAY_MILLIS);
+ }
+ return false;
+ }
+ };
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.activity_setupwizard);
+
+ mVisible = true;
+ mControlsView = findViewById(R.id.fullscreen_content_controls);
+ mContentView = findViewById(R.id.fullscreen_content);
+
+
+ // Set up the user interaction to manually show or hide the system UI.
+ mContentView.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ toggle();
+ }
+ });
+
+ // Upon interacting with UI controls, delay any scheduled hide()
+ // operations to prevent the jarring behavior of controls going away
+ // while interacting with the UI.
+ findViewById(R.id.dummy_button).setOnTouchListener(mDelayHideTouchListener);
+ }
+
+ @Override
+ protected void onPostCreate(Bundle savedInstanceState) {
+ super.onPostCreate(savedInstanceState);
+
+ // Trigger the initial hide() shortly after the activity has been
+ // created, to briefly hint to the user that UI controls
+ // are available.
+ delayedHide(100);
+ }
+
+ private void toggle() {
+ if (mVisible) {
+ hide();
+ } else {
+ show();
+ }
+ }
+
+ private void hide() {
+ // Hide UI first
+ ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.hide();
+ }
+ mControlsView.setVisibility(View.GONE);
+ mVisible = false;
+
+ // Schedule a runnable to remove the status and navigation bar after a delay
+ mHideHandler.removeCallbacks(mShowPart2Runnable);
+ mHideHandler.postDelayed(mHidePart2Runnable, UI_ANIMATION_DELAY);
+ }
+
+ @SuppressLint("InlinedApi")
+ private void show() {
+ // Show the system bar
+ mContentView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
+ | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
+ mVisible = true;
+
+ // Schedule a runnable to display UI elements after a delay
+ mHideHandler.removeCallbacks(mHidePart2Runnable);
+ mHideHandler.postDelayed(mShowPart2Runnable, UI_ANIMATION_DELAY);
+ }
+
+ /**
+ * Schedules a call to hide() in delay milliseconds, canceling any
+ * previously scheduled calls.
+ */
+ private void delayedHide(int delayMillis) {
+ mHideHandler.removeCallbacks(mHideRunnable);
+ mHideHandler.postDelayed(mHideRunnable, delayMillis);
+ }
+}
diff --git a/app/src/main/java/info/nightscout/utils/DefaultValueHelper.java b/app/src/main/java/info/nightscout/utils/DefaultValueHelper.java
new file mode 100644
index 0000000000..ba1aba90b8
--- /dev/null
+++ b/app/src/main/java/info/nightscout/utils/DefaultValueHelper.java
@@ -0,0 +1,90 @@
+package info.nightscout.utils;
+
+import info.nightscout.androidaps.Constants;
+import info.nightscout.androidaps.R;
+
+public class DefaultValueHelper {
+
+ /**
+ * returns the corresponding EatingSoon TempTarget based on the given units (MMOL / MGDL)
+ *
+ * @param units
+ * @return
+ */
+ public double getDefaultEatingSoonTT(String units) {
+ return Constants.MMOL.equals(units) ? Constants.defaultEatingSoonTTmmol
+ : Constants.defaultEatingSoonTTmgdl;
+ }
+
+ /**
+ * returns the corresponding Activity TempTarget based on the given units (MMOL / MGDL)
+ *
+ * @param units
+ * @return
+ */
+ public double getDefaultActivityTT(String units) {
+ return Constants.MMOL.equals(units) ? Constants.defaultActivityTTmmol
+ : Constants.defaultActivityTTmgdl;
+ }
+
+ /**
+ * returns the corresponding Hypo TempTarget based on the given units (MMOL / MGDL)
+ *
+ * @param units
+ * @return
+ */
+ public double getDefaultHypoTT(String units) {
+ return Constants.MMOL.equals(units) ? Constants.defaultHypoTTmmol
+ : Constants.defaultHypoTTmgdl;
+ }
+
+ /**
+ * returns the configured EatingSoon TempTarget, if this is set to 0, the Default-Value is returned.
+ *
+ * @param units
+ * @return
+ */
+ public double determineEatingSoonTT(String units) {
+ double value = SP.getDouble(R.string.key_eatingsoon_target, this.getDefaultEatingSoonTT(units));
+ return value > 0 ? value : this.getDefaultEatingSoonTT(units);
+ }
+
+ public int determineEatingSoonTTDuration() {
+ int value = SP.getInt(R.string.key_eatingsoon_duration, Constants.defaultEatingSoonTTDuration);
+ return value > 0 ? value : Constants.defaultEatingSoonTTDuration;
+ }
+
+
+ /**
+ * returns the configured Activity TempTarget, if this is set to 0, the Default-Value is returned.
+ *
+ * @param units
+ * @return
+ */
+ public double determineActivityTT(String units) {
+ double value = SP.getDouble(R.string.key_activity_target, this.getDefaultActivityTT(units));
+ return value > 0 ? value : this.getDefaultActivityTT(units);
+ }
+
+ public int determineActivityTTDuration() {
+ int value = SP.getInt(R.string.key_activity_duration, Constants.defaultActivityTTDuration);
+ return value > 0 ? value : Constants.defaultActivityTTDuration;
+ }
+
+ /**
+ * returns the configured Hypo TempTarget, if this is set to 0, the Default-Value is returned.
+ *
+ * @param units
+ * @return
+ */
+ public double determineHypoTT(String units) {
+ double value = SP.getDouble(R.string.key_hypo_target, this.getDefaultHypoTT(units));
+ return value > 0 ? value : this.getDefaultHypoTT(units);
+ }
+
+ public int determineHypoTTDuration() {
+ int value = SP.getInt(R.string.key_hypo_duration, Constants.defaultHypoTTDuration);
+ return value > 0 ? value : Constants.defaultHypoTTDuration;
+ }
+
+}
diff --git a/app/src/main/java/info/nightscout/utils/JsonHelper.java b/app/src/main/java/info/nightscout/utils/JsonHelper.java
index ead68132af..503d0bf395 100644
--- a/app/src/main/java/info/nightscout/utils/JsonHelper.java
+++ b/app/src/main/java/info/nightscout/utils/JsonHelper.java
@@ -1,5 +1,7 @@
package info.nightscout.utils;
+import android.support.annotation.Nullable;
+
import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
@@ -17,6 +19,20 @@ public class JsonHelper {
private JsonHelper() {};
+ public static Object safeGetObject(JSONObject json, String fieldName, Object defaultValue) {
+ Object result = defaultValue;
+
+ if (json.has(fieldName)) {
+ try {
+ result = json.get(fieldName);
+ } catch (JSONException ignored) {
+ }
+ }
+
+ return result;
+ }
+
+ @Nullable
public static String safeGetString(JSONObject json, String fieldName) {
String result = null;
diff --git a/app/src/main/java/info/nightscout/utils/LocalAlertUtils.java b/app/src/main/java/info/nightscout/utils/LocalAlertUtils.java
index 58814ceddb..cc1a22355a 100644
--- a/app/src/main/java/info/nightscout/utils/LocalAlertUtils.java
+++ b/app/src/main/java/info/nightscout/utils/LocalAlertUtils.java
@@ -13,10 +13,10 @@ import info.nightscout.androidaps.db.BgReading;
import info.nightscout.androidaps.db.DatabaseHelper;
import info.nightscout.androidaps.interfaces.PumpInterface;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
+import info.nightscout.androidaps.plugins.Loop.LoopPlugin;
+import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification;
import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification;
import info.nightscout.androidaps.plugins.Overview.notifications.Notification;
-import info.nightscout.androidaps.receivers.KeepAliveReceiver;
-import info.nightscout.utils.NSUpload;
/**
* Created by adrian on 17/12/17.
@@ -25,12 +25,12 @@ import info.nightscout.utils.NSUpload;
public class LocalAlertUtils {
private static Logger log = LoggerFactory.getLogger(LocalAlertUtils.class);
- public static int missedReadingsThreshold() {
- return SP.getInt(MainApp.sResources.getString(R.string.key_missed_bg_readings_threshold), 30) * 60 * 1000;
+ public static long missedReadingsThreshold() {
+ return T.mins(SP.getInt(MainApp.sResources.getString(R.string.key_missed_bg_readings_threshold), 30)).msecs();
}
- private static int pumpUnreachableThreshold() {
- return SP.getInt(MainApp.sResources.getString(R.string.key_pump_unreachable_threshold), 30) * 60 * 1000;
+ private static long pumpUnreachableThreshold() {
+ return T.mins(SP.getInt(MainApp.sResources.getString(R.string.key_pump_unreachable_threshold), 30)).msecs();
}
public static void checkPumpUnreachableAlarm(Date lastConnection, boolean isStatusOutdated) {
@@ -38,7 +38,7 @@ public class LocalAlertUtils {
boolean nextAlarmOccurrenceReached = SP.getLong("nextPumpDisconnectedAlarm", 0L) < System.currentTimeMillis();
if (Config.APS && SP.getBoolean(MainApp.sResources.getString(R.string.key_enable_pump_unreachable_alert), true)
- && isStatusOutdated && alarmTimeoutExpired && nextAlarmOccurrenceReached && !ConfigBuilderPlugin.getActiveLoop().isDisconnected()) {
+ && isStatusOutdated && alarmTimeoutExpired && nextAlarmOccurrenceReached && !LoopPlugin.getPlugin().isDisconnected()) {
log.debug("Generating pump unreachable alarm. lastConnection: " + DateUtil.dateAndTimeString(lastConnection) + " isStatusOutdated: " + isStatusOutdated);
Notification n = new Notification(Notification.PUMP_UNREACHABLE, MainApp.sResources.getString(R.string.pump_unreachable), Notification.URGENT);
n.soundId = R.raw.alarm;
@@ -48,11 +48,13 @@ public class LocalAlertUtils {
NSUpload.uploadError(n.text);
}
}
+ if (!isStatusOutdated && !alarmTimeoutExpired)
+ MainApp.bus().post(new EventDismissNotification(Notification.PUMP_UNREACHABLE));
}
/*Presnoozes the alarms with 5 minutes if no snooze exists.
- * Call only at startup!
- */
+ * Call only at startup!
+ */
public static void presnoozeAlarms() {
if (SP.getLong("nextMissedReadingsAlarm", 0l) < System.currentTimeMillis()) {
SP.putLong("nextMissedReadingsAlarm", System.currentTimeMillis() + 5 * 60 * 1000);
@@ -73,7 +75,7 @@ public class LocalAlertUtils {
SP.putLong("nextPumpDisconnectedAlarm", nextPumpDisconnectedAlarm);
}
- public static void notifyPumpStatusRead(){
+ public static void notifyPumpStatusRead() {
//TODO: persist the actual time the pump is read and simplify the whole logic when to alarm
final PumpInterface pump = ConfigBuilderPlugin.getActivePump();
diff --git a/app/src/main/java/info/nightscout/utils/NSUpload.java b/app/src/main/java/info/nightscout/utils/NSUpload.java
index 9b9b940ef9..3cd252f19a 100644
--- a/app/src/main/java/info/nightscout/utils/NSUpload.java
+++ b/app/src/main/java/info/nightscout/utils/NSUpload.java
@@ -7,7 +7,9 @@ import android.content.pm.ResolveInfo;
import android.os.Build;
import android.os.Bundle;
import android.preference.PreferenceManager;
+import android.support.annotation.Nullable;
+import org.apache.commons.lang3.StringUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
@@ -28,6 +30,7 @@ import info.nightscout.androidaps.db.BgReading;
import info.nightscout.androidaps.db.CareportalEvent;
import info.nightscout.androidaps.db.ExtendedBolus;
import info.nightscout.androidaps.db.ProfileSwitch;
+import info.nightscout.androidaps.db.TempTarget;
import info.nightscout.androidaps.db.TemporaryBasal;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.Loop.APSResult;
@@ -256,7 +259,7 @@ public class NSUpload {
}
}
- public static void uploadBolusWizardRecord(DetailedBolusInfo detailedBolusInfo) {
+ public static void uploadTreatmentRecord(DetailedBolusInfo detailedBolusInfo) {
JSONObject data = new JSONObject();
try {
data.put("eventType", detailedBolusInfo.eventType);
@@ -275,6 +278,9 @@ public class NSUpload {
data.put("boluscalc", detailedBolusInfo.boluscalc);
if (detailedBolusInfo.carbTime != 0)
data.put("preBolus", detailedBolusInfo.carbTime);
+ if (!StringUtils.isEmpty(detailedBolusInfo.notes)) {
+ data.put("notes", detailedBolusInfo.notes);
+ }
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
@@ -302,6 +308,30 @@ public class NSUpload {
}
}
+ public static void uploadTempTarget(TempTarget tempTarget) {
+ try {
+ Profile profile = MainApp.getConfigBuilder().getProfile();
+
+ if (profile == null) {
+ log.error("Profile is null. Skipping upload");
+ return;
+ }
+
+ JSONObject data = new JSONObject();
+ data.put("eventType", CareportalEvent.TEMPORARYTARGET);
+ data.put("duration", tempTarget.durationInMinutes);
+ data.put("reason", tempTarget.reason);
+ data.put("targetBottom", Profile.fromMgdlToUnits(tempTarget.low, profile.getUnits()));
+ data.put("targetTop", Profile.fromMgdlToUnits(tempTarget.high, profile.getUnits()));
+ data.put("created_at", DateUtil.toISOString(tempTarget.date));
+ data.put("units", profile.getUnits());
+ data.put("enteredBy", MainApp.instance().getString(R.string.app_name));
+ uploadCareportalEntryToNS(data);
+ } catch (JSONException e) {
+ log.error("Unhandled exception", e);
+ }
+ }
+
public static void updateProfileSwitch(ProfileSwitch profileSwitch) {
try {
JSONObject data = new JSONObject();
@@ -466,7 +496,7 @@ public class NSUpload {
try {
data.put("eventType", "Note");
data.put("created_at", DateUtil.toISOString(new Date()));
- data.put("notes", MainApp.sResources.getString(R.string.androidaps_start));
+ data.put("notes", MainApp.sResources.getString(R.string.androidaps_start)+" - "+ Build.MANUFACTURER + " "+ Build.MODEL);
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
@@ -476,10 +506,10 @@ public class NSUpload {
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
context.sendBroadcast(intent);
DbLogger.dbAdd(intent, data.toString());
- }
+ }
}
- public static void uploadEvent(String careportalEvent, long time) {
+ public static void uploadEvent(String careportalEvent, long time, @Nullable String notes) {
Context context = MainApp.instance().getApplicationContext();
Bundle bundle = new Bundle();
bundle.putString("action", "dbAdd");
@@ -489,6 +519,9 @@ public class NSUpload {
data.put("eventType", careportalEvent);
data.put("created_at", DateUtil.toISOString(time));
data.put("enteredBy", SP.getString("careportal_enteredby", MainApp.gs(R.string.app_name)));
+ if (notes != null) {
+ data.put("notes", notes);
+ }
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
diff --git a/app/src/main/java/info/nightscout/utils/NumberPicker.java b/app/src/main/java/info/nightscout/utils/NumberPicker.java
index 01c7dcb336..64239cbaee 100644
--- a/app/src/main/java/info/nightscout/utils/NumberPicker.java
+++ b/app/src/main/java/info/nightscout/utils/NumberPicker.java
@@ -5,6 +5,7 @@ import android.os.Handler;
import android.os.Message;
import android.text.Editable;
import android.text.TextWatcher;
+import android.text.method.DigitsKeyListener;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.LayoutInflater;
@@ -148,7 +149,7 @@ 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) {
+ if (this.textWatcher != null) {
editText.removeTextChangedListener(this.textWatcher);
}
setParams(initValue, minValue, maxValue, step, formater, allowZero);
@@ -164,6 +165,8 @@ public class NumberPicker extends LinearLayout implements View.OnKeyListener,
this.formater = formater;
this.allowZero = allowZero;
+ editText.setKeyListener(DigitsKeyListener.getInstance(minValue < 0, step != Math.rint(step)));
+
if (textWatcher != null)
editText.removeTextChangedListener(textWatcher);
updateEditText();
@@ -202,7 +205,7 @@ public class NumberPicker extends LinearLayout implements View.OnKeyListener,
updateEditText();
}
- private void dec( int multiplier) {
+ private void dec(int multiplier) {
value -= step * multiplier;
if (value < minValue) {
value = minValue;
diff --git a/app/src/main/java/info/nightscout/utils/SP.java b/app/src/main/java/info/nightscout/utils/SP.java
index 16015d8956..df45996fc2 100644
--- a/app/src/main/java/info/nightscout/utils/SP.java
+++ b/app/src/main/java/info/nightscout/utils/SP.java
@@ -16,6 +16,10 @@ public class SP {
return sharedPreferences.contains(key);
}
+ static public boolean contains(int resourceId) {
+ return sharedPreferences.contains(MainApp.gs(resourceId));
+ }
+
static public String getString(int resourceID, String defaultValue) {
return sharedPreferences.getString(MainApp.sResources.getString(resourceID), defaultValue);
}
@@ -24,7 +28,7 @@ public class SP {
return sharedPreferences.getString(key, defaultValue);
}
- static public boolean getBoolean(int resourceID, boolean defaultValue) {
+ static public boolean getBoolean(int resourceID, Boolean defaultValue) {
try {
return sharedPreferences.getBoolean(MainApp.sResources.getString(resourceID), defaultValue);
} catch (Exception e) {
@@ -32,7 +36,7 @@ public class SP {
}
}
- static public boolean getBoolean(String key, boolean defaultValue) {
+ static public boolean getBoolean(String key, Boolean defaultValue) {
try {
return sharedPreferences.getBoolean(key, defaultValue);
} catch (Exception e) {
diff --git a/app/src/main/res/drawable-hdpi/icon_local_activate.png b/app/src/main/res/drawable-hdpi/icon_local_activate.png
new file mode 100644
index 0000000000..4ef567ffb6
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/icon_local_activate.png differ
diff --git a/app/src/main/res/drawable-hdpi/icon_local_reset.png b/app/src/main/res/drawable-hdpi/icon_local_reset.png
new file mode 100644
index 0000000000..7d38cf0b50
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/icon_local_reset.png differ
diff --git a/app/src/main/res/drawable-hdpi/icon_local_save.png b/app/src/main/res/drawable-hdpi/icon_local_save.png
new file mode 100644
index 0000000000..e5c1d5cedc
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/icon_local_save.png differ
diff --git a/app/src/main/res/drawable-mdpi/icon_local_activate.png b/app/src/main/res/drawable-mdpi/icon_local_activate.png
new file mode 100644
index 0000000000..b39c72b407
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/icon_local_activate.png differ
diff --git a/app/src/main/res/drawable-mdpi/icon_local_reset.png b/app/src/main/res/drawable-mdpi/icon_local_reset.png
new file mode 100644
index 0000000000..ad2e0eaf6d
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/icon_local_reset.png differ
diff --git a/app/src/main/res/drawable-mdpi/icon_local_save.png b/app/src/main/res/drawable-mdpi/icon_local_save.png
new file mode 100644
index 0000000000..843beed523
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/icon_local_save.png differ
diff --git a/app/src/main/res/drawable-xhdpi/icon_local_activate.png b/app/src/main/res/drawable-xhdpi/icon_local_activate.png
new file mode 100644
index 0000000000..75e9af38ed
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/icon_local_activate.png differ
diff --git a/app/src/main/res/drawable-xhdpi/icon_local_reset.png b/app/src/main/res/drawable-xhdpi/icon_local_reset.png
new file mode 100644
index 0000000000..2813cb448d
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/icon_local_reset.png differ
diff --git a/app/src/main/res/drawable-xhdpi/icon_local_save.png b/app/src/main/res/drawable-xhdpi/icon_local_save.png
new file mode 100644
index 0000000000..0cf81430cc
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/icon_local_save.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/icon_local_activate.png b/app/src/main/res/drawable-xxhdpi/icon_local_activate.png
new file mode 100644
index 0000000000..600e6ee61c
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/icon_local_activate.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/icon_local_reset.png b/app/src/main/res/drawable-xxhdpi/icon_local_reset.png
new file mode 100644
index 0000000000..dc9d659dd7
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/icon_local_reset.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/icon_local_save.png b/app/src/main/res/drawable-xxhdpi/icon_local_save.png
new file mode 100644
index 0000000000..20448e4bf9
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/icon_local_save.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/icon_local_activate.png b/app/src/main/res/drawable-xxxhdpi/icon_local_activate.png
new file mode 100644
index 0000000000..2de9ce9d4d
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_local_activate.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/icon_local_reset.png b/app/src/main/res/drawable-xxxhdpi/icon_local_reset.png
new file mode 100644
index 0000000000..ec54479149
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_local_reset.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/icon_local_save.png b/app/src/main/res/drawable-xxxhdpi/icon_local_save.png
new file mode 100644
index 0000000000..f2ecc45ac0
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_local_save.png differ
diff --git a/app/src/main/res/layout/actions_fill_dialog.xml b/app/src/main/res/layout/actions_fill_dialog.xml
index 18a5886246..2883485bf7 100644
--- a/app/src/main/res/layout/actions_fill_dialog.xml
+++ b/app/src/main/res/layout/actions_fill_dialog.xml
@@ -1,97 +1,153 @@
-
+ android:layout_height="wrap_content">
+
+
+ android:layout_gravity="center"
+ android:orientation="horizontal">
+
+
-
+
+
+
+
+ android:text="@string/careportal_pumpsitechange" />
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ android:text="@string/careportal_insulincartridgechange" />
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/activity_setupwizard.xml b/app/src/main/res/layout/activity_setupwizard.xml
new file mode 100644
index 0000000000..706ab33863
--- /dev/null
+++ b/app/src/main/res/layout/activity_setupwizard.xml
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/localprofile_fragment.xml b/app/src/main/res/layout/localprofile_fragment.xml
index a08c6964e9..02aec264f8 100644
--- a/app/src/main/res/layout/localprofile_fragment.xml
+++ b/app/src/main/res/layout/localprofile_fragment.xml
@@ -151,7 +151,7 @@
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:text="@string/activate_profile"
- android:textColor="@color/colorProfileSwitchButton" />
+ android:drawableLeft="@drawable/icon_local_activate" />
+ android:drawableLeft="@drawable/icon_local_reset" />
+ android:drawableLeft="@drawable/icon_local_save" />
diff --git a/app/src/main/res/layout/number_picker_layout.xml b/app/src/main/res/layout/number_picker_layout.xml
index dc8c6b7592..2b143162a1 100644
--- a/app/src/main/res/layout/number_picker_layout.xml
+++ b/app/src/main/res/layout/number_picker_layout.xml
@@ -23,8 +23,7 @@
android:layout_height="match_parent"
android:text="1"
android:textColor="@android:color/black"
- android:inputType="numberDecimal"
- android:digits="0123456789.,"
+ android:inputType="number"
android:gravity="center"
android:imeOptions="actionDone"
/>
diff --git a/app/src/main/res/layout/overview_newcarbs_dialog.xml b/app/src/main/res/layout/overview_newcarbs_dialog.xml
index 25ca0d75d2..8d0a12e5d2 100644
--- a/app/src/main/res/layout/overview_newcarbs_dialog.xml
+++ b/app/src/main/res/layout/overview_newcarbs_dialog.xml
@@ -11,6 +11,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
+
-
-
-
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:orientation="horizontal">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ android:paddingBottom="5dp"
+ android:paddingTop="5dp">
+ android:layout_gravity="center_vertical"
+ android:textStyle="bold"
+ android:text="@string/overview_carbs_label" />
+
+
+ android:layout_gravity="center_vertical"
+ android:text="@string/shortgramm" />
-
-
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/overview_newinsulin_dialog.xml b/app/src/main/res/layout/overview_newinsulin_dialog.xml
index 6a0be08086..8103f4378b 100644
--- a/app/src/main/res/layout/overview_newinsulin_dialog.xml
+++ b/app/src/main/res/layout/overview_newinsulin_dialog.xml
@@ -16,20 +16,31 @@
android:orientation="vertical"
android:padding="10dp">
-
-
-
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:orientation="horizontal">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ android:paddingBottom="5dp"
+ android:paddingTop="5dp">
+ android:layout_gravity="center_vertical"
+ android:textStyle="bold"
+ android:text="@string/overview_insulin_label" />
+
+
+ android:layout_gravity="center_vertical"
+ android:text="@string/insulin_unit_shortname" />
-
-
diff --git a/app/src/main/res/layout/overview_wizard_dialog.xml b/app/src/main/res/layout/overview_wizard_dialog.xml
index 4fbdfd3614..20fdef2ba4 100644
--- a/app/src/main/res/layout/overview_wizard_dialog.xml
+++ b/app/src/main/res/layout/overview_wizard_dialog.xml
@@ -199,6 +199,33 @@
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/values/attrs.xml b/app/src/main/res/values/attrs.xml
new file mode 100644
index 0000000000..7ce840eb60
--- /dev/null
+++ b/app/src/main/res/values/attrs.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index 318e93d9d8..658222722a 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -49,7 +49,7 @@
#FFDD7792
#ca77dd
- #c45026
+ #de7550
#1b5e20
#47c8ff
@@ -62,4 +62,6 @@
#ff827c
#009705
+ #66000000
+
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index abdb0e1160..399557ccd2 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -715,6 +715,8 @@
Connection timed out
Food
g
+ m
+ h
]]>
kJ
En
@@ -995,4 +997,12 @@
openapsmb_max_iob
Maximum total IOB OpenAPS can\'t go over [U]
This value is called Max IOB in OpenAPS context\nOpenAPS will not add more insulin if current IOB is greater than this value
+ Time
+ show_notes_entry_dialogs
+ Show notes field in treatment dialogs
+
+ SetupWizardActivity
+ Dummy Button
+ DUMMY\nCONTENT
+ Setup Wizard
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
index ff95a201a6..c6859e3d2c 100644
--- a/app/src/main/res/values/styles.xml
+++ b/app/src/main/res/values/styles.xml
@@ -24,5 +24,17 @@
- 10sp
+
+
+
+
diff --git a/app/src/main/res/xml/pref_overview.xml b/app/src/main/res/xml/pref_overview.xml
index aa0a188b31..7d2ecc4282 100644
--- a/app/src/main/res/xml/pref_overview.xml
+++ b/app/src/main/res/xml/pref_overview.xml
@@ -110,6 +110,10 @@
android:key="@string/key_show_calibration_button"
android:title="@string/overview_calibration"
android:summary="@string/show_calibration_button_summary"/>
+
diff --git a/app/src/test/java/info/AAPSMocker.java b/app/src/test/java/info/AAPSMocker.java
index 1e11a5f401..c02c69cd07 100644
--- a/app/src/test/java/info/AAPSMocker.java
+++ b/app/src/test/java/info/AAPSMocker.java
@@ -1,11 +1,13 @@
package info;
import android.content.Context;
+import android.content.Intent;
import com.squareup.otto.Bus;
import org.json.JSONException;
import org.json.JSONObject;
+import org.junit.Assert;
import org.powermock.api.mockito.PowerMockito;
import java.util.Locale;
@@ -15,8 +17,10 @@ import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.ConstraintChecker;
import info.nightscout.androidaps.data.Profile;
+import info.nightscout.androidaps.data.ProfileStore;
import info.nightscout.androidaps.db.DatabaseHelper;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
+import info.nightscout.androidaps.plugins.Treatments.TreatmentService;
import info.nightscout.androidaps.queue.CommandQueue;
import info.nightscout.utils.SP;
@@ -33,6 +37,10 @@ import static org.mockito.Mockito.when;
public class AAPSMocker {
private static String validProfile = "{\"dia\":\"3\",\"carbratio\":[{\"time\":\"00:00\",\"value\":\"30\"}],\"carbs_hr\":\"20\",\"delay\":\"20\",\"sens\":[{\"time\":\"00:00\",\"value\":\"100\"},{\"time\":\"2:00\",\"value\":\"110\"}],\"timezone\":\"UTC\",\"basal\":[{\"time\":\"00:00\",\"value\":\"1\"}],\"target_low\":[{\"time\":\"00:00\",\"value\":\"4\"}],\"target_high\":[{\"time\":\"00:00\",\"value\":\"5\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\",\"units\":\"mmol\"}";
private static Profile profile;
+ private static ProfileStore profileStore;
+ public static final String TESTPROFILENAME = "someProfile";
+
+ public static Intent intentSent = null;
public static void mockStrings() {
Locale.setDefault(new Locale("en", "US"));
@@ -81,6 +89,7 @@ public class AAPSMocker {
when(MainApp.gs(R.string.basalprofilenotaligned)).thenReturn("Basal values not aligned to hours: %s");
when(MainApp.gs(R.string.minago)).thenReturn("%d min ago");
when(MainApp.gs(R.string.hoursago)).thenReturn("%.1fh ago");
+ when(MainApp.gs(R.string.careportal_profileswitch)).thenReturn("Profile Switch");
}
public static MainApp mockMainApp() {
@@ -128,6 +137,11 @@ public class AAPSMocker {
when(ConfigBuilderPlugin.getCommandQueue()).thenReturn(queue);
}
+ public static void mockTreatmentService() throws Exception {
+ TreatmentService treatmentService = PowerMockito.mock(TreatmentService.class);
+ PowerMockito.whenNew(TreatmentService.class).withNoArguments().thenReturn(treatmentService);
+ }
+
public static Profile getValidProfile() {
try {
if (profile == null)
@@ -137,6 +151,24 @@ public class AAPSMocker {
return profile;
}
+ public static ProfileStore getValidProfileStore() {
+ try {
+ if (profileStore == null) {
+ JSONObject json = new JSONObject();
+ JSONObject store = new JSONObject();
+ JSONObject profile = new JSONObject(validProfile);
+
+ json.put("defaultProfile", TESTPROFILENAME);
+ json.put("store", store);
+ store.put(TESTPROFILENAME, profile);
+ profileStore = new ProfileStore(json);
+ }
+ } catch (JSONException ignored) {
+ Assert.fail("getValidProfileStore() failed");
+ }
+ return profileStore;
+ }
+
private static MockedBus bus = new MockedBus();
public static void prepareMockedBus() {
diff --git a/app/src/test/java/info/BundleMock.java b/app/src/test/java/info/BundleMock.java
new file mode 100644
index 0000000000..62b4f28db6
--- /dev/null
+++ b/app/src/test/java/info/BundleMock.java
@@ -0,0 +1,223 @@
+package info;
+
+import android.os.Bundle;
+import android.os.Parcelable;
+import android.util.SparseArray;
+
+import org.mockito.Mockito;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.HashMap;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyBoolean;
+import static org.mockito.Matchers.anyByte;
+import static org.mockito.Matchers.anyChar;
+import static org.mockito.Matchers.anyDouble;
+import static org.mockito.Matchers.anyFloat;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.anyLong;
+import static org.mockito.Matchers.anyShort;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.when;
+
+public final class BundleMock {
+
+ public static Bundle mock() {
+ return mock(new HashMap());
+ }
+
+ public static Bundle mock(final HashMap map) {
+
+ Answer unsupported = new Answer() {
+ @Override
+ public Object answer(InvocationOnMock invocation) throws Throwable {
+ throw new UnsupportedOperationException();
+ }
+ };
+ Answer put = new Answer() {
+ @Override
+ public Object answer(InvocationOnMock invocation) throws Throwable {
+ map.put((String)invocation.getArguments()[0], invocation.getArguments()[1]);
+ return null;
+ }
+ };
+ Answer