Merge pull request #107 from MilosKozak/timeedit

Local Profile
This commit is contained in:
Milos Kozak 2017-01-01 13:26:37 +01:00 committed by GitHub
commit fb320968a1
16 changed files with 1052 additions and 20 deletions

View file

@ -107,7 +107,7 @@ android {
dependencies { dependencies {
wearWearApp project(path: ':wear', configuration: 'fullRelease') wearWearApp project(path: ':wear', configuration: 'fullRelease')
compile fileTree(dir: 'libs', include: ['*.jar']) compile fileTree(include: ['*.jar'], dir: 'libs')
compile('com.crashlytics.sdk.android:crashlytics:2.5.7@aar') { compile('com.crashlytics.sdk.android:crashlytics:2.5.7@aar') {
transitive = true; transitive = true;
} }
@ -127,6 +127,11 @@ dependencies {
compile 'com.jjoe64:graphview:4.0.1' compile 'com.jjoe64:graphview:4.0.1'
compile 'com.eclipsesource.j2v8:j2v8:3.1.6@aar' compile 'com.eclipsesource.j2v8:j2v8:3.1.6@aar'
compile 'com.joanzapata.iconify:android-iconify-fontawesome:2.1.1' compile 'com.joanzapata.iconify:android-iconify-fontawesome:2.1.1'
testCompile 'junit:junit:4.12'
compile 'com.google.android.gms:play-services-wearable:7.5.0' compile 'com.google.android.gms:play-services-wearable:7.5.0'
compile 'junit:junit:4.12'
testCompile 'org.json:json:20140107'
testCompile 'org.mockito:mockito-core:2.+'
androidTestCompile 'org.mockito:mockito-core:2.+'
androidTestCompile "com.google.dexmaker:dexmaker:1.2"
androidTestCompile "com.google.dexmaker:dexmaker-mockito:1.2"
} }

View file

@ -24,6 +24,7 @@ import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderFragment;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.DanaR.DanaRFragment; import info.nightscout.androidaps.plugins.DanaR.DanaRFragment;
import info.nightscout.androidaps.plugins.DanaRKorean.DanaRKoreanFragment; import info.nightscout.androidaps.plugins.DanaRKorean.DanaRKoreanFragment;
import info.nightscout.androidaps.plugins.LocalProfile.LocalProfileFragment;
import info.nightscout.androidaps.plugins.Loop.LoopFragment; import info.nightscout.androidaps.plugins.Loop.LoopFragment;
import info.nightscout.androidaps.plugins.MDI.MDIFragment; import info.nightscout.androidaps.plugins.MDI.MDIFragment;
import info.nightscout.androidaps.plugins.NSProfile.NSProfileFragment; import info.nightscout.androidaps.plugins.NSProfile.NSProfileFragment;
@ -83,6 +84,7 @@ public class MainApp extends Application {
if (Config.OPENAPSMAENABLED) pluginsList.add(OpenAPSMAFragment.getPlugin()); if (Config.OPENAPSMAENABLED) pluginsList.add(OpenAPSMAFragment.getPlugin());
pluginsList.add(NSProfileFragment.getPlugin()); pluginsList.add(NSProfileFragment.getPlugin());
pluginsList.add(SimpleProfileFragment.getPlugin()); pluginsList.add(SimpleProfileFragment.getPlugin());
pluginsList.add(LocalProfileFragment.getPlugin());
pluginsList.add(CircadianPercentageProfileFragment.getPlugin()); pluginsList.add(CircadianPercentageProfileFragment.getPlugin());
pluginsList.add(TreatmentsFragment.getPlugin()); pluginsList.add(TreatmentsFragment.getPlugin());
pluginsList.add(TempBasalsFragment.getPlugin()); pluginsList.add(TempBasalsFragment.getPlugin());

View file

@ -0,0 +1,167 @@
package info.nightscout.androidaps.plugins.LocalProfile;
import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.RadioButton;
import com.squareup.otto.Subscribe;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.text.DecimalFormat;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.events.EventInitializationChanged;
import info.nightscout.androidaps.interfaces.FragmentBase;
import info.nightscout.androidaps.plugins.Careportal.Dialogs.NewNSTreatmentDialog;
import info.nightscout.androidaps.plugins.Careportal.OptionsToShow;
import info.nightscout.utils.SafeParse;
import info.nightscout.utils.TimeListEdit;
public class LocalProfileFragment extends Fragment implements FragmentBase {
private static Logger log = LoggerFactory.getLogger(LocalProfileFragment.class);
private static LocalProfilePlugin localProfilePlugin = new LocalProfilePlugin();
public static LocalProfilePlugin getPlugin() {
return localProfilePlugin;
}
EditText diaView;
RadioButton mgdlView;
RadioButton mmolView;
TimeListEdit icView;
TimeListEdit isfView;
EditText carView;
TimeListEdit basalView;
TimeListEdit targetView;
Button profileswitchButton;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Runnable save = new Runnable() {
@Override
public void run() {
localProfilePlugin.storeSettings();
}
};
View layout = inflater.inflate(R.layout.localprofile_fragment, container, false);
diaView = (EditText) layout.findViewById(R.id.localprofile_dia);
mgdlView = (RadioButton) layout.findViewById(R.id.localprofile_mgdl);
mmolView = (RadioButton) layout.findViewById(R.id.localprofile_mmol);
icView = new TimeListEdit(getContext(), layout, R.id.localprofile_ic, MainApp.sResources.getString(R.string.nsprofileview_ic_label), getPlugin().ic, null, new DecimalFormat("0.0"), save);
isfView = new TimeListEdit(getContext(), layout, R.id.localprofile_isf, MainApp.sResources.getString(R.string.nsprofileview_isf_label), getPlugin().isf, null, new DecimalFormat("0.0"), save);
carView = (EditText) layout.findViewById(R.id.localprofile_car);
basalView = new TimeListEdit(getContext(), layout, R.id.localprofile_basal, MainApp.sResources.getString(R.string.nsprofileview_basal_label), getPlugin().basal, null, new DecimalFormat("0.00"), save);
targetView = new TimeListEdit(getContext(), layout, R.id.localprofile_target, MainApp.sResources.getString(R.string.nsprofileview_target_label), getPlugin().targetLow, getPlugin().targetHigh, new DecimalFormat("0.0"), save);
profileswitchButton = (Button) layout.findViewById(R.id.localprofile_profileswitch);
onStatusEvent(null);
mgdlView.setChecked(localProfilePlugin.mgdl);
mmolView.setChecked(localProfilePlugin.mmol);
diaView.setText(localProfilePlugin.dia.toString());
carView.setText(localProfilePlugin.car.toString());
mgdlView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
localProfilePlugin.mgdl = mgdlView.isChecked();
localProfilePlugin.mmol = !localProfilePlugin.mgdl;
mmolView.setChecked(localProfilePlugin.mmol);
localProfilePlugin.storeSettings();
}
});
mmolView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
localProfilePlugin.mmol = mmolView.isChecked();
localProfilePlugin.mgdl = !localProfilePlugin.mmol;
mgdlView.setChecked(localProfilePlugin.mgdl);
localProfilePlugin.storeSettings();
}
});
profileswitchButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
NewNSTreatmentDialog newDialog = new NewNSTreatmentDialog();
final OptionsToShow profileswitch = new OptionsToShow(R.id.careportal_profileswitch, R.string.careportal_profileswitch, true, false, false, false, false, false, false, true, false);
profileswitch.executeProfileSwitch = true;
newDialog.setOptions(profileswitch);
newDialog.show(getFragmentManager(), "NewNSTreatmentDialog");
}
});
TextWatcher textWatch = new TextWatcher() {
@Override
public void afterTextChanged(Editable s) {
}
@Override
public void beforeTextChanged(CharSequence s, int start,
int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start,
int before, int count) {
localProfilePlugin.dia = SafeParse.stringToDouble(diaView.getText().toString());
localProfilePlugin.car = SafeParse.stringToDouble(carView.getText().toString());
localProfilePlugin.storeSettings();
}
};
diaView.addTextChangedListener(textWatch);
carView.addTextChangedListener(textWatch);
onStatusEvent(null);
return layout;
}
@Override
public void onPause() {
super.onPause();
MainApp.bus().unregister(this);
}
@Override
public void onResume() {
super.onResume();
MainApp.bus().register(this);
onStatusEvent(null);
}
@Subscribe
public void onStatusEvent(final EventInitializationChanged e) {
Activity activity = getActivity();
if (activity != null)
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
if (!MainApp.getConfigBuilder().isInitialized() || !MainApp.getConfigBuilder().getPumpDescription().isSetBasalProfileCapable) {
profileswitchButton.setVisibility(View.GONE);
} else {
profileswitchButton.setVisibility(View.VISIBLE);
}
}
});
}
}

View file

@ -0,0 +1,300 @@
package info.nightscout.androidaps.plugins.LocalProfile;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.Constants;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.interfaces.PluginBase;
import info.nightscout.androidaps.interfaces.ProfileInterface;
import info.nightscout.androidaps.plugins.SimpleProfile.SimpleProfileFragment;
import info.nightscout.client.data.NSProfile;
import info.nightscout.utils.SafeParse;
/**
* Created by mike on 05.08.2016.
*/
public class LocalProfilePlugin implements PluginBase, ProfileInterface {
private static Logger log = LoggerFactory.getLogger(LocalProfilePlugin.class);
private static boolean fragmentEnabled = true;
private static boolean fragmentVisible = true;
private static NSProfile convertedProfile = null;
final private String DEFAULTARRAY = "[{\"timeAsSeconds\":0,\"value\":0}]";
boolean mgdl;
boolean mmol;
Double dia;
JSONArray ic;
JSONArray isf;
Double car;
JSONArray basal;
JSONArray targetLow;
JSONArray targetHigh;
public LocalProfilePlugin() {
loadSettings();
}
@Override
public String getFragmentClass() {
return LocalProfileFragment.class.getName();
}
@Override
public int getType() {
return PluginBase.PROFILE;
}
@Override
public String getName() {
return MainApp.instance().getString(R.string.localprofile);
}
@Override
public boolean isEnabled(int type) {
return type == PROFILE && fragmentEnabled;
}
@Override
public boolean isVisibleInTabs(int type) {
return type == PROFILE && fragmentVisible;
}
@Override
public boolean canBeHidden(int type) {
return true;
}
@Override
public void setFragmentEnabled(int type, boolean fragmentEnabled) {
if (type == PROFILE) this.fragmentEnabled = fragmentEnabled;
}
@Override
public void setFragmentVisible(int type, boolean fragmentVisible) {
if (type == PROFILE) this.fragmentVisible = fragmentVisible;
}
public void storeSettings() {
if (Config.logPrefsChange)
log.debug("Storing settings");
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(MainApp.instance().getApplicationContext());
SharedPreferences.Editor editor = settings.edit();
editor.putBoolean("LocalProfile" + "mmol", mmol);
editor.putBoolean("LocalProfile" + "mgdl", mgdl);
editor.putString("LocalProfile" + "dia", dia.toString());
editor.putString("LocalProfile" + "ic", ic.toString());
editor.putString("LocalProfile" + "isf", isf.toString());
editor.putString("LocalProfile" + "car", car.toString());
editor.putString("LocalProfile" + "basal", basal.toString());
editor.putString("LocalProfile" + "targetlow", targetLow.toString());
editor.putString("LocalProfile" + "targethigh", targetHigh.toString());
editor.commit();
createConvertedProfile();
}
private void loadSettings() {
if (Config.logPrefsChange)
log.debug("Loading stored settings");
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(MainApp.instance().getApplicationContext());
if (settings.contains("LocalProfile" + "mgdl"))
try {
mgdl = settings.getBoolean("LocalProfile" + "mgdl", false);
} catch (Exception e) {
log.debug(e.getMessage());
}
else mgdl = false;
if (settings.contains("LocalProfile" + "mmol"))
try {
mmol = settings.getBoolean("LocalProfile" + "mmol", true);
} catch (Exception e) {
log.debug(e.getMessage());
}
else mmol = true;
if (settings.contains("LocalProfile" + "dia"))
try {
dia = SafeParse.stringToDouble(settings.getString("LocalProfile" + "dia", "3"));
} catch (Exception e) {
log.debug(e.getMessage());
}
else dia = 3d;
if (settings.contains("LocalProfile" + "ic"))
try {
ic = new JSONArray(settings.getString("LocalProfile" + "ic", DEFAULTARRAY));
} catch (Exception e) {
log.debug(e.getMessage());
try {
ic = new JSONArray(DEFAULTARRAY);
} catch (JSONException e1) {
e1.printStackTrace();
}
}
else {
try {
ic = new JSONArray(DEFAULTARRAY);
} catch (JSONException e) {
e.printStackTrace();
}
}
if (settings.contains("LocalProfile" + "isf"))
try {
isf = new JSONArray(settings.getString("LocalProfile" + "isf", DEFAULTARRAY));
} catch (Exception e) {
log.debug(e.getMessage());
try {
isf = new JSONArray(DEFAULTARRAY);
} catch (JSONException e1) {
e1.printStackTrace();
}
}
else {
try {
isf = new JSONArray(DEFAULTARRAY);
} catch (JSONException e) {
e.printStackTrace();
}
}
if (settings.contains("LocalProfile" + "car"))
try {
car = SafeParse.stringToDouble(settings.getString("LocalProfile" + "car", "20"));
} catch (Exception e) {
log.debug(e.getMessage());
}
else car = 20d;
if (settings.contains("LocalProfile" + "basal"))
try {
basal = new JSONArray(settings.getString("LocalProfile" + "basal", DEFAULTARRAY));
} catch (Exception e) {
log.debug(e.getMessage());
try {
basal = new JSONArray(DEFAULTARRAY);
} catch (JSONException e1) {
e1.printStackTrace();
}
}
else {
try {
basal = new JSONArray(DEFAULTARRAY);
} catch (JSONException e) {
e.printStackTrace();
}
}
if (settings.contains("LocalProfile" + "targetlow"))
try {
targetLow = new JSONArray(settings.getString("LocalProfile" + "targetlow", DEFAULTARRAY));
} catch (Exception e) {
log.debug(e.getMessage());
try {
targetLow = new JSONArray(DEFAULTARRAY);
} catch (JSONException e1) {
e1.printStackTrace();
}
}
else {
try {
targetLow = new JSONArray(DEFAULTARRAY);
} catch (JSONException e) {
e.printStackTrace();
}
}
if (settings.contains("LocalProfile" + "targethigh"))
try {
targetHigh = new JSONArray(settings.getString("LocalProfile" + "targethigh", DEFAULTARRAY));
} catch (Exception e) {
log.debug(e.getMessage());
try {
targetHigh = new JSONArray(DEFAULTARRAY);
} catch (JSONException e1) {
e1.printStackTrace();
}
}
else {
try {
targetHigh = new JSONArray(DEFAULTARRAY);
} catch (JSONException e) {
e.printStackTrace();
}
}
createConvertedProfile();
}
/*
{
"_id": "576264a12771b7500d7ad184",
"startDate": "2016-06-16T08:35:00.000Z",
"defaultProfile": "Default",
"store": {
"Default": {
"dia": "3",
"carbratio": [{
"time": "00:00",
"value": "30"
}],
"carbs_hr": "20",
"delay": "20",
"sens": [{
"time": "00:00",
"value": "100"
}],
"timezone": "UTC",
"basal": [{
"time": "00:00",
"value": "0.1"
}],
"target_low": [{
"time": "00:00",
"value": "0"
}],
"target_high": [{
"time": "00:00",
"value": "0"
}],
"startDate": "1970-01-01T00:00:00.000Z",
"units": "mmol"
}
},
"created_at": "2016-06-16T08:34:41.256Z"
}
*/
void createConvertedProfile() {
JSONObject json = new JSONObject();
JSONObject store = new JSONObject();
JSONObject profile = new JSONObject();
try {
json.put("defaultProfile", "LocalProfile");
json.put("store", store);
profile.put("dia", dia);
profile.put("carbratio", ic);
profile.put("carbs_hr", car);
profile.put("sens", isf);
profile.put("basal", basal);
profile.put("target_low", targetLow);
profile.put("target_high", targetHigh);
profile.put("units", mgdl ? Constants.MGDL : Constants.MMOL);
store.put("LocalProfile", profile);
} catch (JSONException e) {
e.printStackTrace();
}
convertedProfile = new NSProfile(json, "LocalProfile");
}
@Override
public NSProfile getProfile() {
return convertedProfile;
}
}

View file

@ -11,13 +11,17 @@ import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.Button; import android.widget.Button;
import android.widget.EditText; import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.RadioButton; import android.widget.RadioButton;
import com.squareup.otto.Subscribe; import com.squareup.otto.Subscribe;
import org.json.JSONArray;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.text.DecimalFormat;
import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R; import info.nightscout.androidaps.R;
import info.nightscout.androidaps.events.EventInitializationChanged; import info.nightscout.androidaps.events.EventInitializationChanged;
@ -25,7 +29,9 @@ import info.nightscout.androidaps.interfaces.FragmentBase;
import info.nightscout.androidaps.plugins.Careportal.Dialogs.NewNSTreatmentDialog; import info.nightscout.androidaps.plugins.Careportal.Dialogs.NewNSTreatmentDialog;
import info.nightscout.androidaps.plugins.Careportal.OptionsToShow; import info.nightscout.androidaps.plugins.Careportal.OptionsToShow;
import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification;
import info.nightscout.utils.DecimalFormatter;
import info.nightscout.utils.SafeParse; import info.nightscout.utils.SafeParse;
import info.nightscout.utils.TimeListEdit;
public class SimpleProfileFragment extends Fragment implements FragmentBase { public class SimpleProfileFragment extends Fragment implements FragmentBase {
private static Logger log = LoggerFactory.getLogger(SimpleProfileFragment.class); private static Logger log = LoggerFactory.getLogger(SimpleProfileFragment.class);

View file

@ -0,0 +1,335 @@
package info.nightscout.utils;
import android.content.Context;
import android.os.Build;
import android.text.Editable;
import android.text.Layout;
import android.text.TextWatcher;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Spinner;
import android.widget.TextView;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.text.DateFormat;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
/**
* Created by mike on 29.12.2016.
*/
public class TimeListEdit {
private static Logger log = LoggerFactory.getLogger(TimeListEdit.class);
final int ONEHOURINSECONDS = 60 * 60;
LinearLayout layout;
Context context;
View view;
int resLayoutId;
String label;
JSONArray data1;
JSONArray data2;
NumberFormat formatter;
Runnable save;
public TimeListEdit(Context context, View view, int resLayoutId, String label, JSONArray data1, JSONArray data2, NumberFormat formatter, Runnable save) {
this.context = context;
this.view = view;
this.resLayoutId = resLayoutId;
this.label = label;
this.data1 = data1;
this.data2 = data2;
this.formatter = formatter;
this.save = save;
buildView();
}
private void buildView() {
LayoutInflater inflater = LayoutInflater.from(context);
layout = (LinearLayout) view.findViewById(resLayoutId);
layout.removeAllViews();
TextView textlabel = new TextView(context);
textlabel.setText(label);
textlabel.setGravity(Gravity.LEFT);
LinearLayout.LayoutParams llp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
llp.setMargins(10, 0, 0, 0); // llp.setMargins(left, top, right, bottom);
textlabel.setLayoutParams(llp);
textlabel.setBackgroundColor(MainApp.sResources.getColor(R.color.linearBlockBackground));
if (Build.VERSION.SDK_INT < 23)
textlabel.setTextAppearance(context, android.R.style.TextAppearance_Medium);
else
textlabel.setTextAppearance(android.R.style.TextAppearance_Medium);
layout.addView(textlabel);
for (int i = 0; i < itemsCount(); i++) {
View childview = inflater.inflate(R.layout.timelistedit_element, layout, false);
final Spinner timeSpinner = (Spinner) childview.findViewById(R.id.timelistedit_time);
int previous = i == 0 ? -1 * ONEHOURINSECONDS : secondFromMidnight(i - 1);
int next = i == itemsCount() - 1 ? 24 * ONEHOURINSECONDS : secondFromMidnight(i + 1);
if (i == 0) next = ONEHOURINSECONDS;
fillSpinner(timeSpinner, secondFromMidnight(i), previous, next);
final EditText editText1 = (EditText) childview.findViewById(R.id.timelistedit_edit1);
fillNumber(editText1, value1(i));
final EditText editText2 = ((EditText) childview.findViewById(R.id.timelistedit_edit2));
fillNumber(editText2, value2(i));
if (data2 == null) {
editText2.setVisibility(View.GONE);
}
ImageView addbutton = (ImageView) childview.findViewById(R.id.timelistedit_add);
ImageView removebutton = (ImageView) childview.findViewById(R.id.timelistedit_remove);
if (itemsCount() == 1 && i == 0) {
removebutton.setVisibility(View.GONE);
}
if (itemsCount() >= 24) {
addbutton.setVisibility(View.GONE);
}
final int fixedPos = i;
addbutton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
int seconds = secondFromMidnight(fixedPos);
addItem(fixedPos, seconds, 0, 0);
// for here for the rest of values
for (int i = fixedPos + 1; i < itemsCount(); i++) {
if (secondFromMidnight(i - 1) >= secondFromMidnight(i)) {
editItem(i, secondFromMidnight(i - 1) + ONEHOURINSECONDS, value1(i), value2(i));
}
}
while (itemsCount() > 24 || secondFromMidnight(itemsCount() - 1) > 23 * ONEHOURINSECONDS)
removeItem(itemsCount() - 1);
log();
buildView();
}
});
removebutton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
removeItem(fixedPos);
log();
buildView();
}
});
timeSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
int seconds = DateUtil.toSeconds(timeSpinner.getSelectedItem().toString());
editItem(fixedPos, seconds, value1(fixedPos), value2(fixedPos));
log();
buildView();
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
editItem(fixedPos, 0, value1(fixedPos), value2(fixedPos));
log();
buildView();
}
}
);
editText1.addTextChangedListener(new TextWatcher() {
@Override
public void afterTextChanged(Editable s) {
editItem(fixedPos, secondFromMidnight(fixedPos), SafeParse.stringToDouble(editText1.getText().toString()), value2(fixedPos));
log();
}
@Override
public void beforeTextChanged(CharSequence s, int start,
int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start,
int before, int count) {
}
});
editText2.addTextChangedListener(new TextWatcher() {
@Override
public void afterTextChanged(Editable s) {
editItem(fixedPos, secondFromMidnight(fixedPos), value1(fixedPos), SafeParse.stringToDouble(editText2.getText().toString()));
log();
}
@Override
public void beforeTextChanged(CharSequence s, int start,
int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start,
int before, int count) {
}
});
layout.addView(childview);
}
if (!(itemsCount() > 0 && secondFromMidnight(itemsCount() - 1) == 23 * ONEHOURINSECONDS)) {
ImageView imageView = new ImageView(context);
imageView.setImageResource(R.drawable.add);
LinearLayout.LayoutParams illp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
illp.setMargins(0, 25, 0, 25); // llp.setMargins(left, top, right, bottom);
illp.gravity = Gravity.CENTER;
layout.addView(imageView);
imageView.setLayoutParams(illp);
imageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
addItem(itemsCount(), itemsCount() > 0 ? secondFromMidnight(itemsCount() - 1) + ONEHOURINSECONDS : 0, 0, 0);
log();
buildView();
}
});
}
}
public void fillSpinner(Spinner spinner, int secondsFromMidnight, int previous, int next) {
int posInList = 0;
ArrayList<CharSequence> timeList = new ArrayList<>();
DateFormat df = new SimpleDateFormat("HH:mm");
int pos = 0;
for (int t = previous + ONEHOURINSECONDS; t < next; t += ONEHOURINSECONDS) {
timeList.add(df.format(DateUtil.toDate(t)));
if (secondsFromMidnight == t) posInList = pos;
pos++;
}
ArrayAdapter<CharSequence> adapter = new ArrayAdapter<CharSequence>(context,
android.R.layout.simple_spinner_item, timeList);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
spinner.setSelection(posInList, false);
}
public void fillNumber(EditText edit, Double value) {
if (value.equals(0d))
edit.setText("");
else
edit.setText(formatter.format(value));
}
public int itemsCount() {
return data1.length();
}
public int secondFromMidnight(int index) {
try {
JSONObject item = (JSONObject) data1.get(index);
if (item.has("timeAsSeconds")) {
return item.getInt("timeAsSeconds");
}
} catch (JSONException e) {
e.printStackTrace();
}
return 0;
}
public double value1(int index) {
try {
JSONObject item = (JSONObject) data1.get(index);
if (item.has("value")) {
return item.getDouble("value");
}
} catch (JSONException e) {
e.printStackTrace();
}
return 0d;
}
public double value2(int index) {
if (data2 != null) {
try {
JSONObject item = (JSONObject) data2.get(index);
if (item.has("value")) {
return item.getDouble("value");
}
} catch (JSONException e) {
e.printStackTrace();
}
}
return 0d;
}
public void editItem(int index, int timeAsSeconds, double value1, double value2) {
try {
JSONObject newObject1 = new JSONObject();
newObject1.put("timeAsSeconds", timeAsSeconds);
newObject1.put("value", value1);
data1.put(index, newObject1);
if (data2 != null) {
JSONObject newObject2 = new JSONObject();
newObject2.put("timeAsSeconds", timeAsSeconds);
newObject2.put("value", value2);
data2.put(index, newObject2);
}
if (save != null) save.run();
} catch (JSONException e) {
e.printStackTrace();
}
}
public void addItem(int index, int timeAsSeconds, double value1, double value2) {
try {
// shift data
for (int i = data1.length(); i > index; i--) {
data1.put(i, data1.get(i - 1));
if (data2 != null)
data2.put(i, data2.get(i - 1));
}
// add new object
editItem(index, timeAsSeconds, value1, value2);
if (save != null) save.run();
} catch (JSONException e) {
e.printStackTrace();
}
}
public void removeItem(int index) {
data1.remove(index);
if (data2 != null)
data2.remove(index);
if (save != null) save.run();
}
void log() {
DateFormat df = new SimpleDateFormat("HH:mm");
for (int i = 0; i < data1.length(); i++) {
int pos = 0;
log.debug(i + ": @" + df.format(DateUtil.toDate(secondFromMidnight(i))) + " " + value1(i) + (data2 != null ? " " + value2(i) : ""));
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 420 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 643 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 741 B

View file

@ -0,0 +1,118 @@
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".plugins.LocalProfile.LocalProfileFragment">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/units"
android:textAppearance="?android:attr/textAppearanceMedium"
android:background="@color/linearBlockBackground" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<RadioButton
android:id="@+id/localprofile_mgdl"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/mgdl" />
<RadioButton
android:id="@+id/localprofile_mmol"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/mmol" />
</LinearLayout>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/dia"
android:textAppearance="?android:attr/textAppearanceMedium"
android:background="@color/linearBlockBackground" />
<EditText
android:id="@+id/localprofile_dia"
android:layout_height="wrap_content"
android:inputType="numberDecimal"
android:textAlignment="center"
android:layout_gravity="center_horizontal"
android:layout_width="70dp" />
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/localprofile_ic"></LinearLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/localprofile_isf"></LinearLayout>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/absorption_rate"
android:textAppearance="?android:attr/textAppearanceMedium"
android:background="@color/linearBlockBackground" />
<EditText
android:id="@+id/localprofile_car"
android:layout_height="wrap_content"
android:inputType="numberDecimal"
android:textAlignment="center"
android:layout_gravity="center_horizontal"
android:layout_width="70dp" />
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/localprofile_basal"></LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:id="@+id/localprofile_target">
</LinearLayout>
<Button
android:id="@+id/localprofile_profileswitch"
style="?android:attr/buttonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginBottom="3dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="3dp"
android:layout_weight="1"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:text="@string/send_to_pump"
android:textColor="@color/colorProfileSwitchButton" />
</LinearLayout>
</ScrollView>
</FrameLayout>

View file

@ -28,16 +28,12 @@
android:id="@+id/simpleprofile_mgdl" android:id="@+id/simpleprofile_mgdl"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_column="2"
android:layout_weight="1"
android:text="@string/mgdl" /> android:text="@string/mgdl" />
<RadioButton <RadioButton
android:id="@+id/simpleprofile_mmol" android:id="@+id/simpleprofile_mmol"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_column="3"
android:layout_weight="1"
android:text="@string/mmol" /> android:text="@string/mmol" />
</LinearLayout> </LinearLayout>
@ -45,7 +41,6 @@
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/dia" android:text="@string/dia"
android:textAppearance="?android:attr/textAppearanceMedium" /> android:textAppearance="?android:attr/textAppearanceMedium" />
@ -53,7 +48,6 @@
android:id="@+id/simpleprofile_dia" android:id="@+id/simpleprofile_dia"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_column="2"
android:inputType="numberDecimal" /> android:inputType="numberDecimal" />
<TextView <TextView
@ -66,7 +60,6 @@
android:id="@+id/simpleprofile_ic" android:id="@+id/simpleprofile_ic"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_column="2"
android:inputType="numberDecimal" /> android:inputType="numberDecimal" />
<TextView <TextView
@ -79,7 +72,6 @@
android:id="@+id/simpleprofile_isf" android:id="@+id/simpleprofile_isf"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_column="2"
android:inputType="numberDecimal" /> android:inputType="numberDecimal" />
<TextView <TextView
@ -92,7 +84,6 @@
android:id="@+id/simpleprofile_car" android:id="@+id/simpleprofile_car"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_column="2"
android:inputType="numberDecimal" /> android:inputType="numberDecimal" />
<TextView <TextView
@ -105,7 +96,6 @@
android:id="@+id/simpleprofile_basalrate" android:id="@+id/simpleprofile_basalrate"
android:layout_width="100dp" android:layout_width="100dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_column="2"
android:inputType="numberDecimal" /> android:inputType="numberDecimal" />
<TextView <TextView
@ -123,16 +113,12 @@
android:id="@+id/simpleprofile_targetlow" android:id="@+id/simpleprofile_targetlow"
android:layout_width="100dp" android:layout_width="100dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_column="2"
android:layout_weight="1"
android:inputType="numberDecimal" /> android:inputType="numberDecimal" />
<EditText <EditText
android:id="@+id/simpleprofile_targethigh" android:id="@+id/simpleprofile_targethigh"
android:layout_width="100dp" android:layout_width="100dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_column="2"
android:layout_weight="1"
android:inputType="numberDecimal" /> android:inputType="numberDecimal" />
</LinearLayout> </LinearLayout>
@ -152,6 +138,7 @@
android:paddingRight="10dp" android:paddingRight="10dp"
android:text="@string/send_to_pump" android:text="@string/send_to_pump"
android:textColor="@color/colorProfileSwitchButton" /> android:textColor="@color/colorProfileSwitchButton" />
</LinearLayout> </LinearLayout>
</ScrollView> </ScrollView>

View file

@ -0,0 +1,49 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:orientation="horizontal"
android:paddingTop="5dp"
android:textAppearance="?android:attr/textAppearanceSmall">
<Spinner
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/timelistedit_time"
android:layout_marginTop="10dp" />
<EditText
android:id="@+id/timelistedit_edit1"
android:layout_width="70dp"
android:layout_height="wrap_content"
android:layout_marginLeft="15dp"
android:inputType="numberDecimal"
android:layout_gravity="center_horizontal"
android:textAlignment="center" />
<EditText
android:id="@+id/timelistedit_edit2"
android:layout_width="70dp"
android:layout_height="wrap_content"
android:layout_marginLeft="15dp"
android:inputType="numberDecimal"
android:layout_gravity="center_horizontal"
android:textAlignment="center" />
<ImageView
android:id="@+id/timelistedit_add"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="15dp"
android:src="@drawable/add" />
<ImageView
android:id="@+id/timelistedit_remove"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="15dp"
android:src="@drawable/remove" />
</LinearLayout>

View file

@ -384,4 +384,5 @@
<string name="smscommunicator_bolusdelivered">Bolus %.2fU aplikován úspěšně</string> <string name="smscommunicator_bolusdelivered">Bolus %.2fU aplikován úspěšně</string>
<string name="ongoingnotificaction">Průběžné oznámení</string> <string name="ongoingnotificaction">Průběžné oznámení</string>
<string name="old_data">ZASTARALÉ</string> <string name="old_data">ZASTARALÉ</string>
<string name="localprofile">Místní profil</string>
</resources> </resources>

View file

@ -395,4 +395,5 @@
<string name="old_data">OLD DATA</string> <string name="old_data">OLD DATA</string>
<string name="minago">%dmin ago</string> <string name="minago">%dmin ago</string>
<string name="sms_minago">%dmin ago</string> <string name="sms_minago">%dmin ago</string>
<string name="localprofile">Local Profile</string>
</resources> </resources>

View file

@ -6,20 +6,24 @@ import static org.junit.Assert.*;
public class RoundTest { public class RoundTest {
public RoundTest(){
super();
}
@Test @Test
public void roundTo() { public void roundToTest() throws Exception {
assertEquals( 0.55d, Round.roundTo(0.54d, 0.05d), 0.00000001d ); assertEquals( 0.55d, Round.roundTo(0.54d, 0.05d), 0.00000001d );
assertEquals( 1d, Round.roundTo(1.49d, 1d), 0.00000001d ); assertEquals( 1d, Round.roundTo(1.49d, 1d), 0.00000001d );
} }
@Test @Test
public void floorTo() { public void floorToTest() throws Exception {
assertEquals( 0.5d, Round.floorTo(0.54d, 0.05d), 0.00000001d ); assertEquals( 0.5d, Round.floorTo(0.54d, 0.05d), 0.00000001d );
assertEquals( 1d, Round.floorTo(1.59d, 1d), 0.00000001d ); assertEquals( 1d, Round.floorTo(1.59d, 1d), 0.00000001d );
} }
@Test @Test
public void ceilTo() { public void ceilToTest() throws Exception {
assertEquals( 0.6d, Round.ceilTo(0.54d, 0.1d), 0.00000001d ); assertEquals( 0.6d, Round.ceilTo(0.54d, 0.1d), 0.00000001d );
assertEquals( 2d, Round.ceilTo(1.49999d, 1d), 0.00000001d ); assertEquals( 2d, Round.ceilTo(1.49999d, 1d), 0.00000001d );
} }

View file

@ -0,0 +1,57 @@
package info.nightscout.utils;
import android.content.Context;
import android.view.LayoutInflater;
import org.json.JSONArray;
import org.junit.Test;
import org.mockito.Mock;
import java.lang.reflect.Method;
import java.text.DecimalFormat;
import static org.junit.Assert.*;
import static org.mockito.Mockito.when;
/**
* Created by mike on 30.12.2016.
*/
public class TimeListEditTest {
/*
JSONArray data = new JSONArray();
JSONArray data2 = new JSONArray();
TimeListEdit tle = new TimeListEdit(null, null, 0, "Test1", data, "ic", null, new DecimalFormat("0.00"));
TimeListEdit tle2 = new TimeListEdit(null, null, 0, "Test2", data2, "ic", "ic2", new DecimalFormat("0.00"));
@Test
public void doArrayTest() throws Exception {
tle.addItem(0, 0, 0.1, 0);
tle.addItem(1, 60 * 60, 0.2, 0);
assertEquals(2, tle.itemsCount());
tle.editItem(0, 2 * 60 * 60, 1, 0);
assertEquals(2, tle.itemsCount());
assertEquals(1d, tle.value1(0), 0.00001d);
assertEquals( 2 * 60 * 60, tle.secondFromMidnight(0));
tle.removeItem(0);
assertEquals(0.2d, tle.value1(0), 0.00001d);
assertEquals(0, tle.value2(0), 0.00001d);
assertEquals(60 * 60, tle.secondFromMidnight(0));
//System.out.print(tle2.toString());
assertEquals(0, tle2.itemsCount());
tle2.addItem(0, 0, 1, 2);
assertEquals(1, tle2.itemsCount());
assertEquals(0, tle2.secondFromMidnight(0));
assertEquals(1d, tle2.value1(0), 0.00001d);
assertEquals(2d, tle2.value2(0), 0.00001d);
}
*/
@Test
public void fakeTest() throws Exception {
}
}