allow clone from existing switch

This commit is contained in:
Milos Kozak 2019-12-01 20:42:23 +01:00
parent 0fdc789e1f
commit 702e1f0675
8 changed files with 328 additions and 252 deletions

View file

@ -76,6 +76,11 @@ public class Profile {
} }
} }
// Constructor from profileStore JSON
public Profile(JSONObject json) {
init(json, 100, 0);
}
public Profile(JSONObject json, int percentage, int timeshift) { public Profile(JSONObject json, int percentage, int timeshift) {
init(json, percentage, timeshift); init(json, percentage, timeshift);
} }
@ -101,8 +106,6 @@ public class Profile {
units = json.getString("units").toLowerCase(); units = json.getString("units").toLowerCase();
if (json.has("dia")) if (json.has("dia"))
dia = json.getDouble("dia"); dia = json.getDouble("dia");
if (json.has("dia"))
dia = json.getDouble("dia");
if (json.has("timezone")) if (json.has("timezone"))
timeZone = TimeZone.getTimeZone(json.getString("timezone")); timeZone = TimeZone.getTimeZone(json.getString("timezone"));
isf = json.getJSONArray("sens"); isf = json.getJSONArray("sens");
@ -688,4 +691,112 @@ public class Profile {
public int getTimeshift() { public int getTimeshift() {
return timeshift; return timeshift;
} }
public Profile convertToNonCustomizedProfile() {
JSONObject o = new JSONObject();
try {
o.put("units", units);
o.put("dia", dia);
o.put("timezone", timeZone.getID());
// SENS
JSONArray sens = new JSONArray();
double lastValue = -1d;
for (int i = 0; i < 24; i++) {
int timeAsSeconds = i * 60 * 60;
double value = getIsfTimeFromMidnight(timeAsSeconds);
if (value != lastValue) {
JSONObject item = new JSONObject();
String time;
DecimalFormat df = new DecimalFormat("00");
time = df.format(i) + ":00";
item.put("time", time);
item.put("timeAsSeconds", timeAsSeconds);
item.put("value", value);
lastValue = value;
sens.put(item);
}
}
o.put("sens", sens);
// CARBRATIO
JSONArray carbratio = new JSONArray();
lastValue = -1d;
for (int i = 0; i < 24; i++) {
int timeAsSeconds = i * 60 * 60;
double value = getIcTimeFromMidnight(timeAsSeconds);
if (value != lastValue) {
JSONObject item = new JSONObject();
String time;
DecimalFormat df = new DecimalFormat("00");
time = df.format(i) + ":00";
item.put("time", time);
item.put("timeAsSeconds", timeAsSeconds);
item.put("value", value);
lastValue = value;
carbratio.put(item);
}
}
o.put("carbratio", carbratio);
// BASAL
JSONArray basal = new JSONArray();
lastValue = -1d;
for (int i = 0; i < 24; i++) {
int timeAsSeconds = i * 60 * 60;
double value = getBasalTimeFromMidnight(timeAsSeconds);
if (value != lastValue) {
JSONObject item = new JSONObject();
String time;
DecimalFormat df = new DecimalFormat("00");
time = df.format(i) + ":00";
item.put("time", time);
item.put("timeAsSeconds", timeAsSeconds);
item.put("value", value);
lastValue = value;
basal.put(item);
}
}
o.put("basal", basal);
// TARGET_LOW
JSONArray target_low = new JSONArray();
lastValue = -1d;
for (int i = 0; i < 24; i++) {
int timeAsSeconds = i * 60 * 60;
double value = getTargetLowTimeFromMidnight(timeAsSeconds);
if (value != lastValue) {
JSONObject item = new JSONObject();
String time;
DecimalFormat df = new DecimalFormat("00");
time = df.format(i) + ":00";
item.put("time", time);
item.put("timeAsSeconds", timeAsSeconds);
item.put("value", value);
lastValue = value;
target_low.put(item);
}
}
o.put("target_low", target_low);
// TARGET_HIGH
JSONArray target_high = new JSONArray();
lastValue = -1d;
for (int i = 0; i < 24; i++) {
int timeAsSeconds = i * 60 * 60;
double value = getTargetHighTimeFromMidnight(timeAsSeconds);
if (value != lastValue) {
JSONObject item = new JSONObject();
String time;
DecimalFormat df = new DecimalFormat("00");
time = df.format(i) + ":00";
item.put("time", time);
item.put("timeAsSeconds", timeAsSeconds);
item.put("value", value);
lastValue = value;
target_high.put(item);
}
}
o.put("target_high", target_high);
} catch (JSONException e) {
log.error("Unhandled exception" + e);
}
return new Profile(o);
}
} }

View file

@ -14,12 +14,12 @@ import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.MainApp import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.Profile import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.events.EventInitializationChanged
import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin
import info.nightscout.androidaps.plugins.general.careportal.CareportalFragment import info.nightscout.androidaps.plugins.general.careportal.CareportalFragment
import info.nightscout.androidaps.plugins.general.careportal.Dialogs.NewNSTreatmentDialog import info.nightscout.androidaps.plugins.general.careportal.Dialogs.NewNSTreatmentDialog
import info.nightscout.androidaps.plugins.insulin.InsulinOrefBasePlugin.MIN_DIA import info.nightscout.androidaps.plugins.insulin.InsulinOrefBasePlugin.MIN_DIA
import info.nightscout.androidaps.plugins.profile.local.events.EventLocalProfileChanged
import info.nightscout.androidaps.utils.* import info.nightscout.androidaps.utils.*
import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable import io.reactivex.disposables.CompositeDisposable
@ -60,7 +60,6 @@ class LocalProfileFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
build()
// activate DIA tab // activate DIA tab
processVisibilityOnClick(dia_tab) processVisibilityOnClick(dia_tab)
localprofile_dia_placeholder.visibility = View.VISIBLE localprofile_dia_placeholder.visibility = View.VISIBLE
@ -91,6 +90,7 @@ class LocalProfileFragment : Fragment() {
val pumpDescription = ConfigBuilderPlugin.getPlugin().activePump?.pumpDescription ?: return val pumpDescription = ConfigBuilderPlugin.getPlugin().activePump?.pumpDescription ?: return
val units = if (LocalProfilePlugin.currentProfile().mgdl) Constants.MGDL else Constants.MMOL val units = if (LocalProfilePlugin.currentProfile().mgdl) Constants.MGDL else Constants.MMOL
localprofile_name.removeTextChangedListener(textWatch)
localprofile_name.setText(LocalProfilePlugin.currentProfile().name) localprofile_name.setText(LocalProfilePlugin.currentProfile().name)
localprofile_name.addTextChangedListener(textWatch) localprofile_name.addTextChangedListener(textWatch)
localprofile_dia.setParams(LocalProfilePlugin.currentProfile().dia, HardLimits.MINDIA, HardLimits.MAXDIA, 0.1, DecimalFormat("0.0"), false, localprofile_save, textWatch) localprofile_dia.setParams(LocalProfilePlugin.currentProfile().dia, HardLimits.MINDIA, HardLimits.MAXDIA, 0.1, DecimalFormat("0.0"), false, localprofile_save, textWatch)
@ -179,7 +179,7 @@ class LocalProfileFragment : Fragment() {
localprofile_reset.setOnClickListener { localprofile_reset.setOnClickListener {
LocalProfilePlugin.loadSettings() LocalProfilePlugin.loadSettings()
@Suppress("SETTEXTL18N") @Suppress("SETTEXTL18N")
localprofile_units.text = MainApp.gs(R.string.units) + ": " + (if (LocalProfilePlugin.currentProfile().mgdl) MainApp.gs(R.string.mgdl) else MainApp.gs(R.string.mmol)) localprofile_units.text = MainApp.gs(R.string.units_colon) + " " + (if (LocalProfilePlugin.currentProfile().mgdl) MainApp.gs(R.string.mgdl) else MainApp.gs(R.string.mmol))
localprofile_dia.setParams(LocalProfilePlugin.currentProfile().dia, MIN_DIA, 12.0, 0.1, DecimalFormat("0.0"), false, localprofile_save, textWatch) localprofile_dia.setParams(LocalProfilePlugin.currentProfile().dia, MIN_DIA, 12.0, 0.1, DecimalFormat("0.0"), false, localprofile_save, textWatch)
TimeListEdit(context, view, R.id.localprofile_ic, MainApp.gs(R.string.nsprofileview_ic_label) + ":", LocalProfilePlugin.currentProfile().ic, null, 0.5, 50.0, 0.1, DecimalFormat("0.0"), save) TimeListEdit(context, view, R.id.localprofile_ic, MainApp.gs(R.string.nsprofileview_ic_label) + ":", LocalProfilePlugin.currentProfile().ic, null, 0.5, 50.0, 0.1, DecimalFormat("0.0"), save)
TimeListEdit(context, view, R.id.localprofile_isf, MainApp.gs(R.string.nsprofileview_isf_label) + ":", LocalProfilePlugin.currentProfile().isf, null, 0.5, 500.0, 0.1, DecimalFormat("0.0"), save) TimeListEdit(context, view, R.id.localprofile_isf, MainApp.gs(R.string.nsprofileview_isf_label) + ":", LocalProfilePlugin.currentProfile().isf, null, 0.5, 500.0, 0.1, DecimalFormat("0.0"), save)
@ -202,10 +202,11 @@ class LocalProfileFragment : Fragment() {
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
disposable.add(RxBus disposable.add(RxBus
.toObservable(EventInitializationChanged::class.java) .toObservable(EventLocalProfileChanged::class.java)
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe({ updateGUI() }, { FabricPrivacy.logException(it) }) .subscribe({ build() }, { FabricPrivacy.logException(it) })
) )
build()
} }
@Synchronized @Synchronized
@ -261,5 +262,4 @@ class LocalProfileFragment : Fragment() {
localprofile_basal.visibility = View.GONE localprofile_basal.visibility = View.GONE
localprofile_target.visibility = View.GONE localprofile_target.visibility = View.GONE
} }
} }

View file

@ -3,6 +3,7 @@ package info.nightscout.androidaps.plugins.profile.local
import info.nightscout.androidaps.Constants import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.MainApp import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.data.ProfileStore import info.nightscout.androidaps.data.ProfileStore
import info.nightscout.androidaps.events.EventProfileStoreChanged import info.nightscout.androidaps.events.EventProfileStoreChanged
import info.nightscout.androidaps.interfaces.PluginBase import info.nightscout.androidaps.interfaces.PluginBase
@ -53,7 +54,7 @@ object LocalProfilePlugin : PluginBase(PluginDescription()
internal var targetLow: JSONArray? = null internal var targetLow: JSONArray? = null
internal var targetHigh: JSONArray? = null internal var targetHigh: JSONArray? = null
fun deepClone() : SingleProfile { fun deepClone(): SingleProfile {
val sp = SingleProfile() val sp = SingleProfile()
sp.name = name sp.name = name
sp.mgdl = mgdl sp.mgdl = mgdl
@ -65,6 +66,23 @@ object LocalProfilePlugin : PluginBase(PluginDescription()
sp.targetHigh = JSONArray(targetHigh.toString()) sp.targetHigh = JSONArray(targetHigh.toString())
return sp return sp
} }
fun copyFrom(profile: Profile, newName: String): SingleProfile {
var verifiedName = newName
if (rawProfile?.getSpecificProfile(newName) != null) {
verifiedName += " " + DateUtil.now().toString()
}
val sp = SingleProfile()
sp.name = verifiedName
sp.mgdl = profile.units == Constants.MGDL
sp.dia = profile.dia
sp.ic = JSONArray(profile.data.getJSONArray("carbratio").toString())
sp.isf = JSONArray(profile.data.getJSONArray("sens").toString())
sp.basal = JSONArray(profile.data.getJSONArray("basal").toString())
sp.targetLow = JSONArray(profile.data.getJSONArray("target_low").toString())
sp.targetHigh = JSONArray(profile.data.getJSONArray("target_high").toString())
return sp
}
} }
var isEdited: Boolean = false var isEdited: Boolean = false
@ -336,6 +354,16 @@ object LocalProfilePlugin : PluginBase(PluginDescription()
numOfProfiles++ numOfProfiles++
createAndStoreConvertedProfile() createAndStoreConvertedProfile()
storeSettings() storeSettings()
isEdited = false
}
fun addProfile(p: SingleProfile) {
profiles.add(p)
currentProfileIndex = profiles.size - 1
numOfProfiles++
createAndStoreConvertedProfile()
storeSettings()
isEdited = false
} }
fun removeCurrentProfile() { fun removeCurrentProfile() {
@ -345,6 +373,7 @@ object LocalProfilePlugin : PluginBase(PluginDescription()
currentProfileIndex = 0 currentProfileIndex = 0
createAndStoreConvertedProfile() createAndStoreConvertedProfile()
storeSettings() storeSettings()
isEdited = false
} }
fun createProfileStore(): ProfileStore { fun createProfileStore(): ProfileStore {

View file

@ -0,0 +1,6 @@
package info.nightscout.androidaps.plugins.profile.local.events
import info.nightscout.androidaps.events.Event
class EventLocalProfileChanged : Event() {
}

View file

@ -1,242 +0,0 @@
package info.nightscout.androidaps.plugins.treatments.fragments;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Paint;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import androidx.appcompat.app.AlertDialog;
import androidx.cardview.widget.CardView;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.db.ProfileSwitch;
import info.nightscout.androidaps.db.Source;
import info.nightscout.androidaps.events.EventProfileNeedsUpdate;
import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.plugins.bus.RxBus;
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload;
import info.nightscout.androidaps.plugins.general.nsclient.UploadQueue;
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientRestart;
import info.nightscout.androidaps.utils.DateUtil;
import info.nightscout.androidaps.utils.DecimalFormatter;
import info.nightscout.androidaps.utils.FabricPrivacy;
import info.nightscout.androidaps.utils.SP;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
/**
* Created by mike on 13/01/17.
*/
public class TreatmentsProfileSwitchFragment extends Fragment implements View.OnClickListener {
private Logger log = LoggerFactory.getLogger(L.UI);
private CompositeDisposable disposable = new CompositeDisposable();
RecyclerView recyclerView;
LinearLayoutManager llm;
Button refreshFromNS;
Context context;
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ProfileSwitchViewHolder> {
List<ProfileSwitch> profileSwitchList;
RecyclerViewAdapter(List<ProfileSwitch> profileSwitchList) {
this.profileSwitchList = profileSwitchList;
}
@Override
public ProfileSwitchViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.treatments_profileswitch_item, viewGroup, false);
return new ProfileSwitchViewHolder(v);
}
@Override
public void onBindViewHolder(ProfileSwitchViewHolder holder, int position) {
Profile profile = ProfileFunctions.getInstance().getProfile();
if (profile == null) return;
ProfileSwitch profileSwitch = profileSwitchList.get(position);
holder.ph.setVisibility(profileSwitch.source == Source.PUMP ? View.VISIBLE : View.GONE);
holder.ns.setVisibility(NSUpload.isIdValid(profileSwitch._id) ? View.VISIBLE : View.GONE);
holder.date.setText(DateUtil.dateAndTimeString(profileSwitch.date));
if (!profileSwitch.isEndingEvent()) {
holder.duration.setText(DecimalFormatter.to0Decimal(profileSwitch.durationInMinutes) + " min");
} else {
holder.duration.setText("");
}
holder.name.setText(profileSwitch.getCustomizedName());
if (profileSwitch.isInProgress())
holder.date.setTextColor(ContextCompat.getColor(MainApp.instance(), R.color.colorActive));
else
holder.date.setTextColor(holder.duration.getCurrentTextColor());
holder.remove.setTag(profileSwitch);
holder.name.setTag(profileSwitch);
holder.date.setTag(profileSwitch);
holder.invalid.setVisibility(profileSwitch.isValid() ? View.GONE : View.VISIBLE);
}
@Override
public int getItemCount() {
return profileSwitchList.size();
}
@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
}
public class ProfileSwitchViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
CardView cv;
TextView date;
TextView duration;
TextView name;
TextView remove;
TextView ph;
TextView ns;
TextView invalid;
ProfileSwitchViewHolder(View itemView) {
super(itemView);
cv = (CardView) itemView.findViewById(R.id.profileswitch_cardview);
date = (TextView) itemView.findViewById(R.id.profileswitch_date);
duration = (TextView) itemView.findViewById(R.id.profileswitch_duration);
name = (TextView) itemView.findViewById(R.id.profileswitch_name);
ph = (TextView) itemView.findViewById(R.id.pump_sign);
ns = (TextView) itemView.findViewById(R.id.ns_sign);
invalid = (TextView) itemView.findViewById(R.id.invalid_sign);
remove = (TextView) itemView.findViewById(R.id.profileswitch_remove);
remove.setOnClickListener(this);
remove.setPaintFlags(remove.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG);
name.setOnClickListener(this);
date.setOnClickListener(this);
}
@Override
public void onClick(View v) {
final ProfileSwitch profileSwitch = (ProfileSwitch) v.getTag();
if (profileSwitch == null) {
log.error("profileSwitch == null");
return;
}
switch (v.getId()) {
case R.id.profileswitch_remove:
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(MainApp.gs(R.string.confirmation));
builder.setMessage(MainApp.gs(R.string.removerecord) + "\n" + DateUtil.dateAndTimeString(profileSwitch.date));
builder.setPositiveButton(MainApp.gs(R.string.ok), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
final String _id = profileSwitch._id;
if (NSUpload.isIdValid(_id)) {
NSUpload.removeCareportalEntryFromNS(_id);
} else {
UploadQueue.removeID("dbAdd", _id);
}
MainApp.getDbHelper().delete(profileSwitch);
}
});
builder.setNegativeButton(MainApp.gs(R.string.cancel), null);
builder.show();
break;
case R.id.profileswitch_date:
case R.id.profileswitch_name:
Bundle args = new Bundle();
args.putLong("time", ((ProfileSwitch) v.getTag()).date);
args.putLong("mode", ProfileViewerDialog.Mode.RUNNING_PROFILE.ordinal());
ProfileViewerDialog pvd = new ProfileViewerDialog();
pvd.setArguments(args);
FragmentManager manager = getFragmentManager();
if (manager != null)
pvd.show(manager, "ProfileViewDialog");
break;
}
}
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.treatments_profileswitch_fragment, container, false);
recyclerView = (RecyclerView) view.findViewById(R.id.profileswitch_recyclerview);
recyclerView.setHasFixedSize(true);
llm = new LinearLayoutManager(view.getContext());
recyclerView.setLayoutManager(llm);
RecyclerViewAdapter adapter = new RecyclerViewAdapter(MainApp.getDbHelper().getProfileSwitchData(false));
recyclerView.setAdapter(adapter);
refreshFromNS = (Button) view.findViewById(R.id.profileswitch_refreshfromnightscout);
refreshFromNS.setOnClickListener(this);
context = getContext();
boolean nsUploadOnly = SP.getBoolean(R.string.key_ns_upload_only, false);
if (nsUploadOnly)
refreshFromNS.setVisibility(View.GONE);
return view;
}
@Override
public synchronized void onResume() {
super.onResume();
disposable.add(RxBus.INSTANCE
.toObservable(EventProfileNeedsUpdate.class)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(event -> updateGUI(), FabricPrivacy::logException)
);
updateGUI();
}
@Override
public synchronized void onPause() {
super.onPause();
disposable.clear();
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.profileswitch_refreshfromnightscout:
AlertDialog.Builder builder = new AlertDialog.Builder(this.getContext());
builder.setTitle(MainApp.gs(R.string.confirmation));
builder.setMessage(MainApp.gs(R.string.refresheventsfromnightscout) + "?");
builder.setPositiveButton(MainApp.gs(R.string.ok), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
MainApp.getDbHelper().resetProfileSwitch();
RxBus.INSTANCE.send(new EventNSClientRestart());
}
});
builder.setNegativeButton(MainApp.gs(R.string.cancel), null);
builder.show();
break;
}
}
protected void updateGUI() {
recyclerView.swapAdapter(new RecyclerViewAdapter(MainApp.getDbHelper().getProfileSwitchData(false)), false);
}
}

View file

@ -0,0 +1,160 @@
package info.nightscout.androidaps.plugins.treatments.fragments
import android.content.DialogInterface
import android.graphics.Paint
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.appcompat.app.AlertDialog
import androidx.cardview.widget.CardView
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R
import info.nightscout.androidaps.db.ProfileSwitch
import info.nightscout.androidaps.db.Source
import info.nightscout.androidaps.events.EventProfileNeedsUpdate
import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload
import info.nightscout.androidaps.plugins.general.nsclient.UploadQueue
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientRestart
import info.nightscout.androidaps.plugins.profile.local.LocalProfilePlugin
import info.nightscout.androidaps.plugins.profile.local.events.EventLocalProfileChanged
import info.nightscout.androidaps.plugins.treatments.fragments.TreatmentsProfileSwitchFragment.RecyclerProfileViewAdapter.ProfileSwitchViewHolder
import info.nightscout.androidaps.utils.*
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import kotlinx.android.synthetic.main.treatments_profileswitch_fragment.*
class TreatmentsProfileSwitchFragment : Fragment() {
private val disposable = CompositeDisposable()
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.treatments_profileswitch_fragment, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
profileswitch_recyclerview.setHasFixedSize(true)
profileswitch_recyclerview.layoutManager = LinearLayoutManager(view.context)
profileswitch_recyclerview.adapter = RecyclerProfileViewAdapter(MainApp.getDbHelper().getProfileSwitchData(false))
profileswitch_refreshfromnightscout.setOnClickListener {
val builder = AlertDialog.Builder(this.context!!)
builder.setTitle(MainApp.gs(R.string.confirmation))
builder.setMessage(MainApp.gs(R.string.refresheventsfromnightscout) + "?")
builder.setPositiveButton(MainApp.gs(R.string.ok)) { dialog: DialogInterface?, id: Int ->
MainApp.getDbHelper().resetProfileSwitch()
RxBus.send(EventNSClientRestart())
}
builder.setNegativeButton(MainApp.gs(R.string.cancel), null)
builder.show()
}
if (SP.getBoolean(R.string.key_ns_upload_only, false)) profileswitch_refreshfromnightscout.visibility = View.GONE
}
@Synchronized
override fun onResume() {
super.onResume()
disposable.add(RxBus
.toObservable(EventProfileNeedsUpdate::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ updateGUI() }) { FabricPrivacy.logException(it) }
)
updateGUI()
}
@Synchronized
override fun onPause() {
super.onPause()
disposable.clear()
}
fun updateGUI() =
profileswitch_recyclerview?.swapAdapter(RecyclerProfileViewAdapter(MainApp.getDbHelper().getProfileSwitchData(false)), false)
inner class RecyclerProfileViewAdapter(var profileSwitchList: List<ProfileSwitch>) : RecyclerView.Adapter<ProfileSwitchViewHolder>() {
override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): ProfileSwitchViewHolder {
return ProfileSwitchViewHolder(LayoutInflater.from(viewGroup.context).inflate(R.layout.treatments_profileswitch_item, viewGroup, false))
}
override fun onBindViewHolder(holder: ProfileSwitchViewHolder, position: Int) {
val profileSwitch = profileSwitchList[position]
holder.ph.visibility = if (profileSwitch.source == Source.PUMP) View.VISIBLE else View.GONE
holder.ns.visibility = if (NSUpload.isIdValid(profileSwitch._id)) View.VISIBLE else View.GONE
holder.date.text = DateUtil.dateAndTimeString(profileSwitch.date)
if (!profileSwitch.isEndingEvent) {
holder.duration.text = DecimalFormatter.to0Decimal(profileSwitch.durationInMinutes.toDouble()) + " " + MainApp.gs(R.string.unit_minute_short)
} else {
holder.duration.text = ""
}
holder.name.text = profileSwitch.customizedName
if (profileSwitch.isInProgress) holder.date.setTextColor(ContextCompat.getColor(MainApp.instance(), R.color.colorActive)) else holder.date.setTextColor(holder.duration.currentTextColor)
holder.remove.tag = profileSwitch
holder.clone.tag = profileSwitch
holder.name.tag = profileSwitch
holder.date.tag = profileSwitch
holder.invalid.visibility = if (profileSwitch.isValid()) View.GONE else View.VISIBLE
}
override fun getItemCount(): Int {
return profileSwitchList.size
}
inner class ProfileSwitchViewHolder internal constructor(itemView: View) : RecyclerView.ViewHolder(itemView), View.OnClickListener {
var cv: CardView = itemView.findViewById<View>(R.id.profileswitch_cardview) as CardView
var date: TextView = itemView.findViewById<View>(R.id.profileswitch_date) as TextView
var duration: TextView = itemView.findViewById<View>(R.id.profileswitch_duration) as TextView
var name: TextView = itemView.findViewById<View>(R.id.profileswitch_name) as TextView
var remove: TextView = itemView.findViewById<View>(R.id.profileswitch_remove) as TextView
var clone: TextView = itemView.findViewById<View>(R.id.profileswitch_clone) as TextView
var ph: TextView = itemView.findViewById<View>(R.id.pump_sign) as TextView
var ns: TextView = itemView.findViewById<View>(R.id.ns_sign) as TextView
var invalid: TextView = itemView.findViewById<View>(R.id.invalid_sign) as TextView
override fun onClick(v: View) {
val profileSwitch = v.tag as ProfileSwitch
when (v.id) {
R.id.profileswitch_remove ->
OKDialog.showConfirmation(activity, MainApp.gs(R.string.removerecord) + "\n" + profileSwitch.profileName + "\n" + DateUtil.dateAndTimeString(profileSwitch.date)) {
val id = profileSwitch._id
if (NSUpload.isIdValid(id)) NSUpload.removeCareportalEntryFromNS(id)
else UploadQueue.removeID("dbAdd", id)
MainApp.getDbHelper().delete(profileSwitch)
}
R.id.profileswitch_clone ->
OKDialog.showConfirmation(activity, MainApp.gs(R.string.copytolocalprofile) + "\n" + profileSwitch.customizedName + "\n" + DateUtil.dateAndTimeString(profileSwitch.date)) {
profileSwitch.profileObject?.let {
val nonCustomized = it.convertToNonCustomizedProfile()
LocalProfilePlugin.addProfile(LocalProfilePlugin.SingleProfile().copyFrom(nonCustomized, profileSwitch.customizedName + " " + DateUtil.dateAndTimeString(profileSwitch.date).replace(".", "_")))
RxBus.send(EventLocalProfileChanged())
}
}
R.id.profileswitch_date, R.id.profileswitch_name -> {
val args = Bundle()
args.putLong("time", (v.tag as ProfileSwitch).date)
args.putInt("mode", ProfileViewerDialog.Mode.RUNNING_PROFILE.ordinal)
val pvd = ProfileViewerDialog()
pvd.arguments = args
fragmentManager?.let { pvd.show(it, "ProfileViewDialog") }
}
}
}
init {
remove.setOnClickListener(this)
clone.setOnClickListener(this)
remove.paintFlags = remove.paintFlags or Paint.UNDERLINE_TEXT_FLAG
clone.paintFlags = clone.paintFlags or Paint.UNDERLINE_TEXT_FLAG
name.setOnClickListener(this)
date.setOnClickListener(this)
}
}
}
}

View file

@ -88,6 +88,16 @@
android:text="NS" android:text="NS"
android:textColor="@color/colorSetTempButton" /> android:textColor="@color/colorSetTempButton" />
<TextView
android:id="@+id/profileswitch_clone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingEnd="5dp"
android:paddingStart="10dp"
android:text="@string/clone_label"
android:textAlignment="viewEnd"
android:textColor="@android:color/holo_blue_light" />
<TextView <TextView
android:id="@+id/profileswitch_remove" android:id="@+id/profileswitch_remove"
android:layout_width="wrap_content" android:layout_width="wrap_content"
@ -97,6 +107,7 @@
android:text="@string/overview_quickwizard_item_remove_button" android:text="@string/overview_quickwizard_item_remove_button"
android:textAlignment="viewEnd" android:textAlignment="viewEnd"
android:textColor="@android:color/holo_orange_light" /> android:textColor="@android:color/holo_orange_light" />
</LinearLayout> </LinearLayout>
<View <View

View file

@ -1653,8 +1653,9 @@
<string name="ic_short">IC</string> <string name="ic_short">IC</string>
<string name="isf_short">ISF</string> <string name="isf_short">ISF</string>
<string name="target_short">TARG</string> <string name="target_short">TARG</string>
<string name="clone_label">CLONE</string> <string name="clone_label">Clone</string>
<string name="saveorresetchangesfirst">Save or reset current changes first</string> <string name="saveorresetchangesfirst">Save or reset current changes first</string>
<string name="deletecurrentprofile">Delete current profile?</string> <string name="deletecurrentprofile">Delete current profile?</string>
<string name="copytolocalprofile">Create new local profile from this profile switch?</string>
</resources> </resources>