From 702e1f06753f1a7c3d7b73bc64633ee6e99af9c3 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Sun, 1 Dec 2019 20:42:23 +0100 Subject: [PATCH] allow clone from existing switch --- .../nightscout/androidaps/data/Profile.java | 115 ++++++++- .../profile/local/LocalProfileFragment.kt | 12 +- .../profile/local/LocalProfilePlugin.kt | 31 ++- .../local/events/EventLocalProfileChanged.kt | 6 + .../TreatmentsProfileSwitchFragment.java | 242 ------------------ .../TreatmentsProfileSwitchFragment.kt | 160 ++++++++++++ .../layout/treatments_profileswitch_item.xml | 11 + app/src/main/res/values/strings.xml | 3 +- 8 files changed, 328 insertions(+), 252 deletions(-) create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/profile/local/events/EventLocalProfileChanged.kt delete mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/treatments/fragments/TreatmentsProfileSwitchFragment.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/treatments/fragments/TreatmentsProfileSwitchFragment.kt 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 4193d75369..93c95dda51 100644 --- a/app/src/main/java/info/nightscout/androidaps/data/Profile.java +++ b/app/src/main/java/info/nightscout/androidaps/data/Profile.java @@ -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) { init(json, percentage, timeshift); } @@ -101,8 +106,6 @@ public class Profile { units = json.getString("units").toLowerCase(); if (json.has("dia")) dia = json.getDouble("dia"); - if (json.has("dia")) - dia = json.getDouble("dia"); if (json.has("timezone")) timeZone = TimeZone.getTimeZone(json.getString("timezone")); isf = json.getJSONArray("sens"); @@ -688,4 +691,112 @@ public class Profile { public int getTimeshift() { 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); + } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfileFragment.kt b/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfileFragment.kt index 6133aa8a2d..67f9f91817 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfileFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfileFragment.kt @@ -14,12 +14,12 @@ import info.nightscout.androidaps.Constants import info.nightscout.androidaps.MainApp import info.nightscout.androidaps.R import info.nightscout.androidaps.data.Profile -import info.nightscout.androidaps.events.EventInitializationChanged import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin import info.nightscout.androidaps.plugins.general.careportal.CareportalFragment import info.nightscout.androidaps.plugins.general.careportal.Dialogs.NewNSTreatmentDialog import info.nightscout.androidaps.plugins.insulin.InsulinOrefBasePlugin.MIN_DIA +import info.nightscout.androidaps.plugins.profile.local.events.EventLocalProfileChanged import info.nightscout.androidaps.utils.* import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.disposables.CompositeDisposable @@ -60,7 +60,6 @@ class LocalProfileFragment : Fragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - build() // activate DIA tab processVisibilityOnClick(dia_tab) localprofile_dia_placeholder.visibility = View.VISIBLE @@ -91,6 +90,7 @@ class LocalProfileFragment : Fragment() { val pumpDescription = ConfigBuilderPlugin.getPlugin().activePump?.pumpDescription ?: return val units = if (LocalProfilePlugin.currentProfile().mgdl) Constants.MGDL else Constants.MMOL + localprofile_name.removeTextChangedListener(textWatch) localprofile_name.setText(LocalProfilePlugin.currentProfile().name) localprofile_name.addTextChangedListener(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 { LocalProfilePlugin.loadSettings() @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) 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) @@ -202,10 +202,11 @@ class LocalProfileFragment : Fragment() { override fun onResume() { super.onResume() disposable.add(RxBus - .toObservable(EventInitializationChanged::class.java) + .toObservable(EventLocalProfileChanged::class.java) .observeOn(AndroidSchedulers.mainThread()) - .subscribe({ updateGUI() }, { FabricPrivacy.logException(it) }) + .subscribe({ build() }, { FabricPrivacy.logException(it) }) ) + build() } @Synchronized @@ -261,5 +262,4 @@ class LocalProfileFragment : Fragment() { localprofile_basal.visibility = View.GONE localprofile_target.visibility = View.GONE } - } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfilePlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfilePlugin.kt index 5d2021325f..525bd8847b 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfilePlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfilePlugin.kt @@ -3,6 +3,7 @@ package info.nightscout.androidaps.plugins.profile.local import info.nightscout.androidaps.Constants import info.nightscout.androidaps.MainApp import info.nightscout.androidaps.R +import info.nightscout.androidaps.data.Profile import info.nightscout.androidaps.data.ProfileStore import info.nightscout.androidaps.events.EventProfileStoreChanged import info.nightscout.androidaps.interfaces.PluginBase @@ -53,7 +54,7 @@ object LocalProfilePlugin : PluginBase(PluginDescription() internal var targetLow: JSONArray? = null internal var targetHigh: JSONArray? = null - fun deepClone() : SingleProfile { + fun deepClone(): SingleProfile { val sp = SingleProfile() sp.name = name sp.mgdl = mgdl @@ -65,6 +66,23 @@ object LocalProfilePlugin : PluginBase(PluginDescription() sp.targetHigh = JSONArray(targetHigh.toString()) 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 @@ -336,6 +354,16 @@ object LocalProfilePlugin : PluginBase(PluginDescription() numOfProfiles++ createAndStoreConvertedProfile() storeSettings() + isEdited = false + } + + fun addProfile(p: SingleProfile) { + profiles.add(p) + currentProfileIndex = profiles.size - 1 + numOfProfiles++ + createAndStoreConvertedProfile() + storeSettings() + isEdited = false } fun removeCurrentProfile() { @@ -345,6 +373,7 @@ object LocalProfilePlugin : PluginBase(PluginDescription() currentProfileIndex = 0 createAndStoreConvertedProfile() storeSettings() + isEdited = false } fun createProfileStore(): ProfileStore { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/events/EventLocalProfileChanged.kt b/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/events/EventLocalProfileChanged.kt new file mode 100644 index 0000000000..c84eaecd7f --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/events/EventLocalProfileChanged.kt @@ -0,0 +1,6 @@ +package info.nightscout.androidaps.plugins.profile.local.events + +import info.nightscout.androidaps.events.Event + +class EventLocalProfileChanged : Event() { +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/treatments/fragments/TreatmentsProfileSwitchFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/treatments/fragments/TreatmentsProfileSwitchFragment.java deleted file mode 100644 index 2d06b2824f..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/treatments/fragments/TreatmentsProfileSwitchFragment.java +++ /dev/null @@ -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 { - - List profileSwitchList; - - RecyclerViewAdapter(List 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); - } -} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/treatments/fragments/TreatmentsProfileSwitchFragment.kt b/app/src/main/java/info/nightscout/androidaps/plugins/treatments/fragments/TreatmentsProfileSwitchFragment.kt new file mode 100644 index 0000000000..28b4f04452 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/treatments/fragments/TreatmentsProfileSwitchFragment.kt @@ -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) : RecyclerView.Adapter() { + 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(R.id.profileswitch_cardview) as CardView + var date: TextView = itemView.findViewById(R.id.profileswitch_date) as TextView + var duration: TextView = itemView.findViewById(R.id.profileswitch_duration) as TextView + var name: TextView = itemView.findViewById(R.id.profileswitch_name) as TextView + var remove: TextView = itemView.findViewById(R.id.profileswitch_remove) as TextView + var clone: TextView = itemView.findViewById(R.id.profileswitch_clone) as TextView + var ph: TextView = itemView.findViewById(R.id.pump_sign) as TextView + var ns: TextView = itemView.findViewById(R.id.ns_sign) as TextView + var invalid: TextView = itemView.findViewById(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) + } + } + } +} \ No newline at end of file diff --git a/app/src/main/res/layout/treatments_profileswitch_item.xml b/app/src/main/res/layout/treatments_profileswitch_item.xml index de457274ff..a0eeb78a63 100644 --- a/app/src/main/res/layout/treatments_profileswitch_item.xml +++ b/app/src/main/res/layout/treatments_profileswitch_item.xml @@ -88,6 +88,16 @@ android:text="NS" android:textColor="@color/colorSetTempButton" /> + + + IC ISF TARG - CLONE + Clone Save or reset current changes first Delete current profile? + Create new local profile from this profile switch?