Add history treatments option menu
This commit is contained in:
parent
fef8421e79
commit
67e5fb8dc7
34 changed files with 1289 additions and 745 deletions
|
@ -1,13 +1,13 @@
|
|||
package info.nightscout.androidaps.activities
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentTransaction
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.activities.fragments.*
|
||||
import info.nightscout.androidaps.databinding.TreatmentsFragmentBinding
|
||||
import info.nightscout.androidaps.extensions.toVisibility
|
||||
import info.nightscout.androidaps.interfaces.ActivePlugin
|
||||
import info.nightscout.androidaps.utils.buildHelper.BuildHelper
|
||||
import javax.inject.Inject
|
||||
|
@ -23,40 +23,60 @@ class TreatmentsActivity : NoSplashAppCompatActivity() {
|
|||
super.onCreate(savedInstanceState)
|
||||
binding = TreatmentsFragmentBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
|
||||
//binding.tempBasals.visibility = buildHelper.isEngineeringMode().toVisibility()
|
||||
//binding.extendedBoluses.visibility = (buildHelper.isEngineeringMode() && !activePlugin.activePump.isFakingTempsByExtendedBoluses).toVisibility()
|
||||
|
||||
binding.treatments.setOnClickListener {
|
||||
setFragment(TreatmentsBolusCarbsFragment())
|
||||
setBackgroundColorOnSelected(it)
|
||||
supportActionBar?.title = rh.gs(R.string.carbs_and_bolus)
|
||||
}
|
||||
binding.extendedBoluses.setOnClickListener {
|
||||
setFragment(TreatmentsExtendedBolusesFragment())
|
||||
setBackgroundColorOnSelected(it)
|
||||
supportActionBar?.title = rh.gs(R.string.extended_bolus)
|
||||
}
|
||||
binding.tempBasals.setOnClickListener {
|
||||
setFragment(TreatmentsTemporaryBasalsFragment())
|
||||
setBackgroundColorOnSelected(it)
|
||||
supportActionBar?.title = rh.gs(R.string.tempbasal_label)
|
||||
}
|
||||
binding.tempTargets.setOnClickListener {
|
||||
setFragment(TreatmentsTempTargetFragment())
|
||||
setBackgroundColorOnSelected(it)
|
||||
supportActionBar?.title = rh.gs(R.string.tempt_targets)
|
||||
}
|
||||
binding.profileSwitches.setOnClickListener {
|
||||
setFragment(TreatmentsProfileSwitchFragment())
|
||||
setBackgroundColorOnSelected(it)
|
||||
supportActionBar?.title = rh.gs(R.string.profile_changes)
|
||||
}
|
||||
binding.careportal.setOnClickListener {
|
||||
setFragment(TreatmentsCareportalFragment())
|
||||
setBackgroundColorOnSelected(it)
|
||||
supportActionBar?.title = rh.gs(R.string.careportal)
|
||||
}
|
||||
binding.userentry.setOnClickListener {
|
||||
setFragment(TreatmentsUserEntryFragment())
|
||||
setBackgroundColorOnSelected(it)
|
||||
supportActionBar?.title = rh.gs(R.string.user_action)
|
||||
}
|
||||
setFragment(TreatmentsBolusCarbsFragment())
|
||||
setBackgroundColorOnSelected(binding.treatments)
|
||||
setSupportActionBar(binding.toolbar)
|
||||
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
||||
supportActionBar?.title = rh.gs(R.string.carbs_and_bolus)
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
return when (item.itemId) {
|
||||
android.R.id.home -> {
|
||||
finish()
|
||||
true
|
||||
}
|
||||
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
private fun setFragment(selectedFragment: Fragment) {
|
||||
|
|
|
@ -3,9 +3,10 @@ package info.nightscout.androidaps.activities.fragments
|
|||
import android.annotation.SuppressLint
|
||||
import android.graphics.Paint
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.*
|
||||
import android.widget.CompoundButton
|
||||
import android.view.ActionMode
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import dagger.android.support.DaggerFragment
|
||||
|
@ -79,9 +80,14 @@ class TreatmentsBolusCarbsFragment : DaggerFragment() {
|
|||
|
||||
private var _binding: TreatmentsBolusCarbsFragmentBinding? = null
|
||||
|
||||
// This property is only valid between onCreateView and
|
||||
// onDestroyView.
|
||||
// This property is only valid between onCreateView and onDestroyView.
|
||||
private val binding get() = _binding!!
|
||||
private var selectedItems: MutableList<MealLink> = mutableListOf()
|
||||
private var showInvalidated = false
|
||||
private var removeActionMode: ActionMode? = null
|
||||
|
||||
// val TAG = "TreatmentMenu"
|
||||
private var toolbar: Toolbar? = null
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View =
|
||||
TreatmentsBolusCarbsFragmentBinding.inflate(inflater, container, false).also { _binding = it }.root
|
||||
|
@ -89,92 +95,10 @@ class TreatmentsBolusCarbsFragment : DaggerFragment() {
|
|||
@SuppressLint("CheckResult")
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
setHasOptionsMenu(true)
|
||||
toolbar = activity?.findViewById(R.id.toolbar)
|
||||
binding.recyclerview.setHasFixedSize(true)
|
||||
binding.recyclerview.layoutManager = LinearLayoutManager(view.context)
|
||||
|
||||
binding.refreshFromNightscout.setOnClickListener {
|
||||
activity?.let { activity ->
|
||||
OKDialog.showConfirmation(activity, rh.gs(R.string.refresheventsfromnightscout) + "?") {
|
||||
uel.log(Action.TREATMENTS_NS_REFRESH, Sources.Treatments)
|
||||
disposable +=
|
||||
Completable.fromAction {
|
||||
repository.deleteAllBolusCalculatorResults()
|
||||
repository.deleteAllBoluses()
|
||||
repository.deleteAllCarbs()
|
||||
}
|
||||
.subscribeOn(aapsSchedulers.io)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribeBy(
|
||||
onError = { aapsLogger.error("Error removing entries", it) },
|
||||
onComplete = {
|
||||
rxBus.send(EventTreatmentChange())
|
||||
rxBus.send(EventNewHistoryData(0, false))
|
||||
}
|
||||
)
|
||||
rxBus.send(EventNSClientRestart())
|
||||
}
|
||||
}
|
||||
}
|
||||
binding.deleteFutureTreatments.setOnClickListener {
|
||||
activity?.let { activity ->
|
||||
OKDialog.showConfirmation(activity, rh.gs(R.string.overview_treatment_label), rh.gs(R.string.deletefuturetreatments) + "?", Runnable {
|
||||
uel.log(Action.DELETE_FUTURE_TREATMENTS, Sources.Treatments)
|
||||
repository
|
||||
.getBolusesDataFromTime(dateUtil.now(), false)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe { list ->
|
||||
list.forEach { bolus ->
|
||||
disposable += repository.runTransactionForResult(InvalidateBolusTransaction(bolus.id))
|
||||
.subscribe(
|
||||
{ result -> result.invalidated.forEach { aapsLogger.debug(LTag.DATABASE, "Invalidated bolus $it") } },
|
||||
{ aapsLogger.error(LTag.DATABASE, "Error while invalidating bolus", it) }
|
||||
)
|
||||
}
|
||||
}
|
||||
repository
|
||||
.getCarbsDataFromTimeNotExpanded(dateUtil.now(), false)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe { list ->
|
||||
list.forEach { carb ->
|
||||
if (carb.duration == 0L)
|
||||
disposable += repository.runTransactionForResult(InvalidateCarbsTransaction(carb.id))
|
||||
.subscribe(
|
||||
{ result -> result.invalidated.forEach { aapsLogger.debug(LTag.DATABASE, "Invalidated carbs $it") } },
|
||||
{ aapsLogger.error(LTag.DATABASE, "Error while invalidating carbs", it) }
|
||||
)
|
||||
else {
|
||||
disposable += repository.runTransactionForResult(CutCarbsTransaction(carb.id, dateUtil.now()))
|
||||
.subscribe(
|
||||
{ result ->
|
||||
result.invalidated.forEach { aapsLogger.debug(LTag.DATABASE, "Invalidated carbs $it") }
|
||||
result.updated.forEach { aapsLogger.debug(LTag.DATABASE, "Updated (cut end) carbs $it") }
|
||||
},
|
||||
{ aapsLogger.error(LTag.DATABASE, "Error while invalidating carbs", it) }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
repository
|
||||
.getBolusCalculatorResultsDataFromTime(dateUtil.now(), false)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe { list ->
|
||||
list.forEach { bolusCalc ->
|
||||
disposable += repository.runTransactionForResult(InvalidateBolusCalculatorResultTransaction(bolusCalc.id))
|
||||
.subscribe(
|
||||
{ result -> result.invalidated.forEach { aapsLogger.debug(LTag.DATABASE, "Invalidated bolusCalculatorResult $it") } },
|
||||
{ aapsLogger.error(LTag.DATABASE, "Error while invalidating bolusCalculatorResult", it) }
|
||||
)
|
||||
}
|
||||
}
|
||||
binding.deleteFutureTreatments.visibility = View.GONE
|
||||
})
|
||||
}
|
||||
}
|
||||
val nsUploadOnly = !sp.getBoolean(R.string.key_ns_receive_insulin, false) || !sp.getBoolean(R.string.key_ns_receive_carbs, false) || !buildHelper.isEngineeringMode()
|
||||
if (nsUploadOnly) binding.refreshFromNightscout.visibility = View.GONE
|
||||
binding.showInvalidated.setOnCheckedChangeListener { _, _ ->
|
||||
rxBus.send(EventTreatmentUpdateGui())
|
||||
}
|
||||
}
|
||||
|
||||
private fun bolusMealLinksWithInvalid(now: Long) = repository
|
||||
|
@ -204,8 +128,8 @@ class TreatmentsBolusCarbsFragment : DaggerFragment() {
|
|||
fun swapAdapter() {
|
||||
val now = System.currentTimeMillis()
|
||||
|
||||
if (binding.showInvalidated.isChecked)
|
||||
disposable += carbsMealLinksWithInvalid(now)
|
||||
disposable += if (showInvalidated)
|
||||
carbsMealLinksWithInvalid(now)
|
||||
.zipWith(bolusMealLinksWithInvalid(now)) { first, second -> first + second }
|
||||
.zipWith(calcResultMealLinksWithInvalid(now)) { first, second -> first + second }
|
||||
.map { ml ->
|
||||
|
@ -217,10 +141,9 @@ class TreatmentsBolusCarbsFragment : DaggerFragment() {
|
|||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe { list ->
|
||||
binding.recyclerview.swapAdapter(RecyclerViewAdapter(list), true)
|
||||
binding.deleteFutureTreatments.visibility = list.isNotEmpty().toVisibility()
|
||||
}
|
||||
else
|
||||
disposable += carbsMealLinks(now)
|
||||
carbsMealLinks(now)
|
||||
.zipWith(bolusMealLinks(now)) { first, second -> first + second }
|
||||
.zipWith(calcResultMealLinks(now)) { first, second -> first + second }
|
||||
.map { ml ->
|
||||
|
@ -232,7 +155,6 @@ class TreatmentsBolusCarbsFragment : DaggerFragment() {
|
|||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe { list ->
|
||||
binding.recyclerview.swapAdapter(RecyclerViewAdapter(list), true)
|
||||
binding.deleteFutureTreatments.visibility = list.isNotEmpty().toVisibility()
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -267,13 +189,14 @@ class TreatmentsBolusCarbsFragment : DaggerFragment() {
|
|||
@Synchronized
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
removeActionMode?.let { it.finish() }
|
||||
binding.recyclerview.adapter = null // avoid leaks
|
||||
_binding = null
|
||||
}
|
||||
|
||||
private fun timestamp(ml: MealLink): Long = ml.bolusCalculatorResult?.let { it.timestamp } ?: ml.bolus?.let { it.timestamp } ?: ml.carbs?.let { it.timestamp } ?: 0L
|
||||
private fun timestamp(ml: MealLink): Long = ml.bolusCalculatorResult?.timestamp ?: ml.bolus?.timestamp ?: ml.carbs?.timestamp ?: 0L
|
||||
|
||||
inner class RecyclerViewAdapter internal constructor(var mealLinks: List<MealLink>) : RecyclerView.Adapter<RecyclerViewAdapter.MealLinkLoadedViewHolder>() {
|
||||
inner class RecyclerViewAdapter internal constructor(private var mealLinks: List<MealLink>) : RecyclerView.Adapter<RecyclerViewAdapter.MealLinkLoadedViewHolder>() {
|
||||
|
||||
override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): MealLinkLoadedViewHolder =
|
||||
MealLinkLoadedViewHolder(LayoutInflater.from(viewGroup.context).inflate(R.layout.treatments_bolus_carbs_item, viewGroup, false))
|
||||
|
@ -287,13 +210,13 @@ class TreatmentsBolusCarbsFragment : DaggerFragment() {
|
|||
holder.binding.date.text = dateUtil.dateString(timestamp(ml))
|
||||
|
||||
// Metadata
|
||||
holder.binding.metadataLayout.visibility = (ml.bolusCalculatorResult != null && (ml.bolusCalculatorResult.isValid || binding.showInvalidated.isChecked)).toVisibility()
|
||||
holder.binding.metadataLayout.visibility = (ml.bolusCalculatorResult != null && (ml.bolusCalculatorResult.isValid || showInvalidated)).toVisibility()
|
||||
ml.bolusCalculatorResult?.let { bolusCalculatorResult ->
|
||||
holder.binding.calcTime.text = dateUtil.timeString(bolusCalculatorResult.timestamp)
|
||||
}
|
||||
|
||||
// Bolus
|
||||
holder.binding.bolusLayout.visibility = (ml.bolus != null && (ml.bolus.isValid || binding.showInvalidated.isChecked)).toVisibility()
|
||||
holder.binding.bolusLayout.visibility = (ml.bolus != null && (ml.bolus.isValid || showInvalidated)).toVisibility()
|
||||
ml.bolus?.let { bolus ->
|
||||
holder.binding.bolusTime.text = dateUtil.timeString(bolus.timestamp)
|
||||
holder.binding.insulin.text = rh.gs(R.string.formatinsulinunits, bolus.amount)
|
||||
|
@ -321,7 +244,7 @@ class TreatmentsBolusCarbsFragment : DaggerFragment() {
|
|||
}
|
||||
}
|
||||
// Carbs
|
||||
holder.binding.carbsLayout.visibility = (ml.carbs != null && (ml.carbs.isValid || binding.showInvalidated.isChecked)).toVisibility()
|
||||
holder.binding.carbsLayout.visibility = (ml.carbs != null && (ml.carbs.isValid || showInvalidated)).toVisibility()
|
||||
ml.carbs?.let { carbs ->
|
||||
holder.binding.carbsTime.text = dateUtil.timeString(carbs.timestamp)
|
||||
holder.binding.carbs.text = rh.gs(R.string.format_carbs, carbs.amount.toInt())
|
||||
|
@ -331,18 +254,26 @@ class TreatmentsBolusCarbsFragment : DaggerFragment() {
|
|||
holder.binding.carbsInvalid.visibility = carbs.isValid.not().toVisibility()
|
||||
}
|
||||
|
||||
holder.binding.bolusRemove.visibility = (ml.bolus?.isValid == true).toVisibility()
|
||||
holder.binding.carbsRemove.visibility = (ml.carbs?.isValid == true).toVisibility()
|
||||
holder.binding.bolusRemove.tag = ml
|
||||
holder.binding.carbsRemove.tag = ml
|
||||
val onChange = CompoundButton.OnCheckedChangeListener { _, value ->
|
||||
if (value) {
|
||||
selectedItems.add(ml)
|
||||
} else {
|
||||
selectedItems.remove(ml)
|
||||
}
|
||||
removeActionMode?.title = rh.gs(R.string.count_selected, selectedItems.size)
|
||||
}
|
||||
holder.binding.cbBolusRemove.visibility = ((ml.bolus?.isValid == true) && (removeActionMode != null)).toVisibility()
|
||||
holder.binding.cbBolusRemove.setOnCheckedChangeListener(onChange)
|
||||
|
||||
holder.binding.cbCarbsRemove.visibility = (ml.carbs?.isValid == true && (removeActionMode != null)).toVisibility()
|
||||
holder.binding.cbCarbsRemove.setOnCheckedChangeListener(onChange)
|
||||
|
||||
holder.binding.calculation.tag = ml
|
||||
val nextTimestamp = if (mealLinks.size != position + 1) timestamp(mealLinks[position + 1]) else 0L
|
||||
holder.binding.delimiter.visibility = dateUtil.isSameDay(timestamp(ml), nextTimestamp).toVisibility()
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
return mealLinks.size
|
||||
}
|
||||
override fun getItemCount() = mealLinks.size
|
||||
|
||||
inner class MealLinkLoadedViewHolder internal constructor(view: View) : RecyclerView.ViewHolder(view) {
|
||||
|
||||
|
@ -359,35 +290,203 @@ class TreatmentsBolusCarbsFragment : DaggerFragment() {
|
|||
}
|
||||
}
|
||||
binding.calculation.paintFlags = binding.calculation.paintFlags or Paint.UNDERLINE_TEXT_FLAG
|
||||
binding.bolusRemove.setOnClickListener { ml ->
|
||||
val bolus = (ml.tag as MealLink?)?.bolus ?: return@setOnClickListener
|
||||
activity?.let { activity ->
|
||||
val text = rh.gs(R.string.configbuilder_insulin) + ": " +
|
||||
rh.gs(R.string.formatinsulinunits, bolus.amount) + "\n" +
|
||||
rh.gs(R.string.date) + ": " + dateUtil.dateAndTimeString(bolus.timestamp)
|
||||
OKDialog.showConfirmation(activity, rh.gs(R.string.removerecord), text, Runnable {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||
inflater.inflate(R.menu.menu_treatments_carbs_bolus, menu)
|
||||
super.onCreateOptionsMenu(menu, inflater)
|
||||
}
|
||||
|
||||
override fun onPrepareOptionsMenu(menu: Menu) {
|
||||
menu.findItem(R.id.nav_hide_invalidated)?.isVisible = showInvalidated
|
||||
menu.findItem(R.id.nav_show_invalidated)?.isVisible = !showInvalidated
|
||||
val nsUploadOnly = !sp.getBoolean(R.string.key_ns_receive_insulin, false) || !sp.getBoolean(R.string.key_ns_receive_carbs, false) || !buildHelper.isEngineeringMode()
|
||||
menu.findItem(R.id.nav_refresh_ns)?.isVisible = !nsUploadOnly
|
||||
val hasItems = (binding.recyclerview.adapter?.itemCount ?: 0) > 0
|
||||
menu.findItem(R.id.nav_delete_future)?.isVisible = hasItems
|
||||
|
||||
return super.onPrepareOptionsMenu(menu)
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
return when (item.itemId) {
|
||||
R.id.nav_remove_items -> {
|
||||
removeActionMode = toolbar?.startActionMode(RemoveActionModeCallback())
|
||||
true
|
||||
}
|
||||
|
||||
R.id.nav_show_invalidated -> {
|
||||
showInvalidated = true
|
||||
rxBus.send(EventTreatmentUpdateGui())
|
||||
true
|
||||
}
|
||||
|
||||
R.id.nav_hide_invalidated -> {
|
||||
showInvalidated = false
|
||||
rxBus.send(EventTreatmentUpdateGui())
|
||||
true
|
||||
}
|
||||
|
||||
R.id.nav_delete_future -> {
|
||||
deleteFutureTreatments()
|
||||
true
|
||||
}
|
||||
|
||||
R.id.nav_refresh_ns -> {
|
||||
refreshFromNightScout()
|
||||
true
|
||||
}
|
||||
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
private fun refreshFromNightScout() {
|
||||
activity?.let { activity ->
|
||||
OKDialog.showConfirmation(activity, rh.gs(R.string.refresheventsfromnightscout) + "?") {
|
||||
uel.log(Action.TREATMENTS_NS_REFRESH, Sources.Treatments)
|
||||
disposable +=
|
||||
Completable.fromAction {
|
||||
repository.deleteAllBolusCalculatorResults()
|
||||
repository.deleteAllBoluses()
|
||||
repository.deleteAllCarbs()
|
||||
}
|
||||
.subscribeOn(aapsSchedulers.io)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribeBy(
|
||||
onError = { aapsLogger.error("Error removing entries", it) },
|
||||
onComplete = {
|
||||
rxBus.send(EventTreatmentChange())
|
||||
rxBus.send(EventNewHistoryData(0, false))
|
||||
}
|
||||
)
|
||||
rxBus.send(EventNSClientRestart())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun deleteFutureTreatments() {
|
||||
activity?.let { activity ->
|
||||
OKDialog.showConfirmation(activity, rh.gs(R.string.overview_treatment_label), rh.gs(R.string.deletefuturetreatments) + "?", Runnable {
|
||||
uel.log(Action.DELETE_FUTURE_TREATMENTS, Sources.Treatments)
|
||||
disposable += repository
|
||||
.getBolusesDataFromTime(dateUtil.now(), false)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe { list ->
|
||||
list.forEach { bolus ->
|
||||
disposable += repository.runTransactionForResult(InvalidateBolusTransaction(bolus.id))
|
||||
.subscribe(
|
||||
{ result -> result.invalidated.forEach { aapsLogger.debug(LTag.DATABASE, "Invalidated bolus $it") } },
|
||||
{ aapsLogger.error(LTag.DATABASE, "Error while invalidating bolus", it) }
|
||||
)
|
||||
}
|
||||
}
|
||||
disposable += repository
|
||||
.getCarbsDataFromTimeNotExpanded(dateUtil.now(), false)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe { list ->
|
||||
list.forEach { carb ->
|
||||
if (carb.duration == 0L)
|
||||
disposable += repository.runTransactionForResult(InvalidateCarbsTransaction(carb.id))
|
||||
.subscribe(
|
||||
{ result -> result.invalidated.forEach { aapsLogger.debug(LTag.DATABASE, "Invalidated carbs $it") } },
|
||||
{ aapsLogger.error(LTag.DATABASE, "Error while invalidating carbs", it) }
|
||||
)
|
||||
else {
|
||||
disposable += repository.runTransactionForResult(CutCarbsTransaction(carb.id, dateUtil.now()))
|
||||
.subscribe(
|
||||
{ result ->
|
||||
result.invalidated.forEach { aapsLogger.debug(LTag.DATABASE, "Invalidated carbs $it") }
|
||||
result.updated.forEach { aapsLogger.debug(LTag.DATABASE, "Updated (cut end) carbs $it") }
|
||||
},
|
||||
{ aapsLogger.error(LTag.DATABASE, "Error while invalidating carbs", it) }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
disposable += repository
|
||||
.getBolusCalculatorResultsDataFromTime(dateUtil.now(), false)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe { list ->
|
||||
list.forEach { bolusCalc ->
|
||||
disposable += repository.runTransactionForResult(InvalidateBolusCalculatorResultTransaction(bolusCalc.id))
|
||||
.subscribe(
|
||||
{ result -> result.invalidated.forEach { aapsLogger.debug(LTag.DATABASE, "Invalidated bolusCalculatorResult $it") } },
|
||||
{ aapsLogger.error(LTag.DATABASE, "Error while invalidating bolusCalculatorResult", it) }
|
||||
)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
inner class RemoveActionModeCallback : ActionMode.Callback {
|
||||
|
||||
override fun onCreateActionMode(mode: ActionMode, menu: Menu?): Boolean {
|
||||
mode.menuInflater.inflate(R.menu.menu_delete_selection, menu)
|
||||
selectedItems = mutableListOf()
|
||||
mode.title = rh.gs(R.string.count_selected, selectedItems.size)
|
||||
binding.recyclerview.adapter?.notifyDataSetChanged()
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onPrepareActionMode(mode: ActionMode?, menu: Menu?) = false
|
||||
|
||||
override fun onActionItemClicked(mode: ActionMode, item: MenuItem): Boolean {
|
||||
return when (item.itemId) {
|
||||
R.id.remove_selected -> {
|
||||
removeSelected()
|
||||
mode.finish()
|
||||
true
|
||||
}
|
||||
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroyActionMode(mode: ActionMode?) {
|
||||
removeActionMode = null
|
||||
binding.recyclerview.adapter?.notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
|
||||
private fun getConfirmationText(): String {
|
||||
if (selectedItems.size == 1) {
|
||||
val mealLink = selectedItems.first()
|
||||
val bolus = mealLink.bolus
|
||||
if (bolus != null)
|
||||
return rh.gs(R.string.configbuilder_insulin) + ": " +
|
||||
rh.gs(R.string.formatinsulinunits, bolus.amount) + "\n" +
|
||||
rh.gs(R.string.date) + ": " + dateUtil.dateAndTimeString(bolus.timestamp)
|
||||
val carbs = mealLink.carbs
|
||||
if (carbs != null)
|
||||
return rh.gs(R.string.carbs) + ": " +
|
||||
rh.gs(R.string.carbs) + ": " + rh.gs(R.string.format_carbs, carbs.amount.toInt()) + "\n" +
|
||||
rh.gs(R.string.date) + ": " + dateUtil.dateAndTimeString(carbs.timestamp)
|
||||
}
|
||||
return rh.gs(R.string.confirm_remove_multiple_items, selectedItems.size)
|
||||
}
|
||||
|
||||
fun removeSelected() {
|
||||
if (selectedItems.size > 0)
|
||||
activity?.let { activity ->
|
||||
OKDialog.showConfirmation(activity, rh.gs(R.string.removerecord), getConfirmationText(), Runnable {
|
||||
selectedItems.forEach { ml ->
|
||||
ml.bolus?.let { bolus ->
|
||||
uel.log(
|
||||
Action.BOLUS_REMOVED, Sources.Treatments,
|
||||
ValueWithUnit.Timestamp(bolus.timestamp),
|
||||
ValueWithUnit.Insulin(bolus.amount)
|
||||
//ValueWithUnit.Gram(mealLinkLoaded.carbs.toInt())
|
||||
)
|
||||
disposable += repository.runTransactionForResult(InvalidateBolusTransaction(bolus.id))
|
||||
.subscribe(
|
||||
{ result -> result.invalidated.forEach { aapsLogger.debug(LTag.DATABASE, "Invalidated bolus $it") } },
|
||||
{ aapsLogger.error(LTag.DATABASE, "Error while invalidating bolus", it) }
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
binding.bolusRemove.paintFlags = binding.bolusRemove.paintFlags or Paint.UNDERLINE_TEXT_FLAG
|
||||
binding.carbsRemove.setOnClickListener { ml ->
|
||||
val carb = (ml.tag as MealLink?)?.carbs ?: return@setOnClickListener
|
||||
activity?.let { activity ->
|
||||
val text = rh.gs(R.string.carbs) + ": " +
|
||||
rh.gs(R.string.carbs) + ": " + rh.gs(R.string.format_carbs, carb.amount.toInt()) + "\n" +
|
||||
rh.gs(R.string.date) + ": " + dateUtil.dateAndTimeString(carb.timestamp)
|
||||
OKDialog.showConfirmation(activity, rh.gs(R.string.removerecord), text, Runnable {
|
||||
}
|
||||
ml.carbs?.let { carb ->
|
||||
uel.log(
|
||||
Action.CARBS_REMOVED, Sources.Treatments,
|
||||
ValueWithUnit.Timestamp(carb.timestamp),
|
||||
|
@ -398,11 +497,12 @@ class TreatmentsBolusCarbsFragment : DaggerFragment() {
|
|||
{ result -> result.invalidated.forEach { aapsLogger.debug(LTag.DATABASE, "Invalidated carbs $it") } },
|
||||
{ aapsLogger.error(LTag.DATABASE, "Error while invalidating carbs", it) }
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
binding.carbsRemove.paintFlags = binding.carbsRemove.paintFlags or Paint.UNDERLINE_TEXT_FLAG
|
||||
selectedItems = mutableListOf()
|
||||
}, Runnable {
|
||||
selectedItems = mutableListOf()
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
package info.nightscout.androidaps.activities.fragments
|
||||
|
||||
import android.graphics.Paint
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.*
|
||||
import android.view.ActionMode
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import dagger.android.support.DaggerFragment
|
||||
|
@ -60,11 +59,14 @@ class TreatmentsCareportalFragment : DaggerFragment() {
|
|||
private val disposable = CompositeDisposable()
|
||||
|
||||
private val millsToThePast = T.days(30).msecs()
|
||||
private var selectedItems: MutableList<TherapyEvent> = mutableListOf()
|
||||
private var showInvalidated = false
|
||||
private var toolbar: Toolbar? = null
|
||||
private var removeActionMode: ActionMode? = null
|
||||
|
||||
private var _binding: TreatmentsCareportalFragmentBinding? = null
|
||||
|
||||
// This property is only valid between onCreateView and
|
||||
// onDestroyView.
|
||||
// This property is only valid between onCreateView and onDestroyView.
|
||||
private val binding get() = _binding!!
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View =
|
||||
|
@ -72,46 +74,44 @@ class TreatmentsCareportalFragment : DaggerFragment() {
|
|||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
toolbar = activity?.findViewById(R.id.toolbar)
|
||||
setHasOptionsMenu(true)
|
||||
binding.recyclerview.setHasFixedSize(true)
|
||||
binding.recyclerview.layoutManager = LinearLayoutManager(view.context)
|
||||
binding.refreshFromNightscout.setOnClickListener {
|
||||
activity?.let { activity ->
|
||||
OKDialog.showConfirmation(activity, rh.gs(R.string.careportal), rh.gs(R.string.refresheventsfromnightscout) + " ?", Runnable {
|
||||
uel.log(Action.CAREPORTAL_NS_REFRESH, Sources.Treatments)
|
||||
disposable += Completable.fromAction { repository.deleteAllTherapyEventsEntries() }
|
||||
.subscribeOn(aapsSchedulers.io)
|
||||
.subscribeBy(
|
||||
onError = { aapsLogger.error("Error removing entries", it) },
|
||||
onComplete = { rxBus.send(EventTherapyEventChange()) }
|
||||
)
|
||||
rxBus.send(EventNSClientRestart())
|
||||
})
|
||||
}
|
||||
}
|
||||
binding.removeAndroidapsStartedEvents.setOnClickListener {
|
||||
activity?.let { activity ->
|
||||
OKDialog.showConfirmation(activity, rh.gs(R.string.careportal), rh.gs(R.string.careportal_removestartedevents), Runnable {
|
||||
uel.log(Action.RESTART_EVENTS_REMOVED, Sources.Treatments)
|
||||
repository.runTransactionForResult(InvalidateAAPSStartedTherapyEventTransaction(rh.gs(R.string.androidaps_start)))
|
||||
.subscribe(
|
||||
{ result -> result.invalidated.forEach { aapsLogger.debug(LTag.DATABASE, "Invalidated therapy event $it") } },
|
||||
{ aapsLogger.error(LTag.DATABASE, "Error while invalidating therapy event", it) }
|
||||
)
|
||||
}, null)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val nsUploadOnly = !sp.getBoolean(R.string.key_ns_receive_therapy_events, false) || !buildHelper.isEngineeringMode()
|
||||
if (nsUploadOnly) binding.refreshFromNightscout.visibility = View.GONE
|
||||
binding.showInvalidated.setOnCheckedChangeListener { _, _ ->
|
||||
rxBus.send(EventTreatmentUpdateGui())
|
||||
private fun refreshFromNightscout() {
|
||||
activity?.let { activity ->
|
||||
OKDialog.showConfirmation(activity, rh.gs(R.string.careportal), rh.gs(R.string.refresheventsfromnightscout) + " ?", Runnable {
|
||||
uel.log(Action.CAREPORTAL_NS_REFRESH, Sources.Treatments)
|
||||
disposable += Completable.fromAction { repository.deleteAllTherapyEventsEntries() }
|
||||
.subscribeOn(aapsSchedulers.io)
|
||||
.subscribeBy(
|
||||
onError = { aapsLogger.error("Error removing entries", it) },
|
||||
onComplete = { rxBus.send(EventTherapyEventChange()) }
|
||||
)
|
||||
rxBus.send(EventNSClientRestart())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
private fun removeStartedEvents() {
|
||||
activity?.let { activity ->
|
||||
OKDialog.showConfirmation(activity, rh.gs(R.string.careportal), rh.gs(R.string.careportal_removestartedevents), Runnable {
|
||||
uel.log(Action.RESTART_EVENTS_REMOVED, Sources.Treatments)
|
||||
disposable += repository.runTransactionForResult(InvalidateAAPSStartedTherapyEventTransaction(rh.gs(R.string.androidaps_start)))
|
||||
.subscribe(
|
||||
{ result -> result.invalidated.forEach { aapsLogger.debug(LTag.DATABASE, "Invalidated therapy event $it") } },
|
||||
{ aapsLogger.error(LTag.DATABASE, "Error while invalidating therapy event", it) }
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fun swapAdapter() {
|
||||
val now = System.currentTimeMillis()
|
||||
disposable +=
|
||||
if (binding.showInvalidated.isChecked)
|
||||
if (showInvalidated)
|
||||
repository
|
||||
.getTherapyEventDataIncludingInvalidFromTime(now - millsToThePast, false)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
|
@ -148,6 +148,7 @@ class TreatmentsCareportalFragment : DaggerFragment() {
|
|||
@Synchronized
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
removeActionMode?.let { it.finish() }
|
||||
binding.recyclerview.adapter = null // avoid leaks
|
||||
_binding = null
|
||||
}
|
||||
|
@ -170,42 +171,135 @@ class TreatmentsCareportalFragment : DaggerFragment() {
|
|||
holder.binding.duration.text = if (therapyEvent.duration == 0L) "" else dateUtil.niceTimeScalar(therapyEvent.duration, rh)
|
||||
holder.binding.note.text = therapyEvent.note
|
||||
holder.binding.type.text = translator.translate(therapyEvent.type)
|
||||
holder.binding.remove.tag = therapyEvent
|
||||
holder.binding.cbRemove.visibility = (therapyEvent.isValid && (removeActionMode != null)).toVisibility()
|
||||
holder.binding.cbRemove.setOnCheckedChangeListener { _, value ->
|
||||
if (value) {
|
||||
selectedItems.add(therapyEvent)
|
||||
} else {
|
||||
selectedItems.remove(therapyEvent)
|
||||
}
|
||||
removeActionMode?.title = rh.gs(R.string.count_selected, selectedItems.size)
|
||||
}
|
||||
val nextTimestamp = if (therapyList.size != position + 1) therapyList[position + 1].timestamp else 0L
|
||||
holder.binding.delimiter.visibility = dateUtil.isSameDay(therapyEvent.timestamp, nextTimestamp).toVisibility()
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
return therapyList.size
|
||||
}
|
||||
override fun getItemCount() = therapyList.size
|
||||
|
||||
inner class TherapyEventsViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
||||
|
||||
val binding = TreatmentsCareportalItemBinding.bind(view)
|
||||
|
||||
init {
|
||||
binding.remove.setOnClickListener { v: View ->
|
||||
val therapyEvent = v.tag as TherapyEvent
|
||||
activity?.let { activity ->
|
||||
val text = rh.gs(R.string.eventtype) + ": " + translator.translate(therapyEvent.type) + "\n" +
|
||||
rh.gs(R.string.notes_label) + ": " + (therapyEvent.note
|
||||
?: "") + "\n" +
|
||||
rh.gs(R.string.date) + ": " + dateUtil.dateAndTimeString(therapyEvent.timestamp)
|
||||
OKDialog.showConfirmation(activity, rh.gs(R.string.removerecord), text, Runnable {
|
||||
uel.log(Action.CAREPORTAL_REMOVED, Sources.Treatments, therapyEvent.note ,
|
||||
ValueWithUnit.Timestamp(therapyEvent.timestamp),
|
||||
ValueWithUnit.TherapyEventType(therapyEvent.type))
|
||||
disposable += repository.runTransactionForResult(InvalidateTherapyEventTransaction(therapyEvent.id))
|
||||
.subscribe(
|
||||
{ result -> result.invalidated.forEach { aapsLogger.debug(LTag.DATABASE, "Invalidated therapy event $it") } },
|
||||
{ aapsLogger.error(LTag.DATABASE, "Error while invalidating therapy event", it) }
|
||||
)
|
||||
}, null)
|
||||
}
|
||||
}
|
||||
binding.remove.paintFlags = binding.remove.paintFlags or Paint.UNDERLINE_TEXT_FLAG
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||
inflater.inflate(R.menu.menu_treatments_careportal, menu)
|
||||
super.onCreateOptionsMenu(menu, inflater)
|
||||
}
|
||||
|
||||
override fun onPrepareOptionsMenu(menu: Menu) {
|
||||
menu.findItem(R.id.nav_hide_invalidated)?.isVisible = showInvalidated
|
||||
menu.findItem(R.id.nav_show_invalidated)?.isVisible = !showInvalidated
|
||||
val nsUploadOnly = !sp.getBoolean(R.string.key_ns_receive_therapy_events, false) || !buildHelper.isEngineeringMode()
|
||||
menu.findItem(R.id.nav_refresh_ns)?.isVisible = !nsUploadOnly
|
||||
|
||||
return super.onPrepareOptionsMenu(menu)
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
return when (item.itemId) {
|
||||
R.id.nav_remove_items -> {
|
||||
removeActionMode = toolbar?.startActionMode(RemoveActionModeCallback())
|
||||
true
|
||||
}
|
||||
|
||||
R.id.nav_show_invalidated -> {
|
||||
showInvalidated = true
|
||||
rxBus.send(EventTreatmentUpdateGui())
|
||||
true
|
||||
}
|
||||
|
||||
R.id.nav_hide_invalidated -> {
|
||||
showInvalidated = false
|
||||
rxBus.send(EventTreatmentUpdateGui())
|
||||
true
|
||||
}
|
||||
|
||||
R.id.nav_remove_started_events -> {
|
||||
removeStartedEvents()
|
||||
true
|
||||
}
|
||||
|
||||
R.id.nav_refresh_ns -> {
|
||||
refreshFromNightscout()
|
||||
true
|
||||
}
|
||||
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
inner class RemoveActionModeCallback : ActionMode.Callback {
|
||||
|
||||
override fun onCreateActionMode(mode: ActionMode, menu: Menu?): Boolean {
|
||||
mode.menuInflater.inflate(R.menu.menu_delete_selection, menu)
|
||||
selectedItems = mutableListOf()
|
||||
mode.title = rh.gs(R.string.count_selected, selectedItems.size)
|
||||
binding.recyclerview.adapter?.notifyDataSetChanged()
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onPrepareActionMode(mode: ActionMode?, menu: Menu?) = false
|
||||
|
||||
override fun onActionItemClicked(mode: ActionMode, item: MenuItem): Boolean {
|
||||
return when (item.itemId) {
|
||||
R.id.remove_selected -> {
|
||||
removeSelected()
|
||||
mode.finish()
|
||||
true
|
||||
}
|
||||
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroyActionMode(mode: ActionMode?) {
|
||||
removeActionMode = null
|
||||
binding.recyclerview.adapter?.notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
|
||||
private fun getConfirmationText(): String {
|
||||
if (selectedItems.size == 1) {
|
||||
val therapyEvent = selectedItems.first()
|
||||
return rh.gs(R.string.eventtype) + ": " + translator.translate(therapyEvent.type) + "\n" +
|
||||
rh.gs(R.string.notes_label) + ": " + (therapyEvent.note ?: "") + "\n" +
|
||||
rh.gs(R.string.date) + ": " + dateUtil.dateAndTimeString(therapyEvent.timestamp)
|
||||
}
|
||||
return rh.gs(R.string.confirm_remove_multiple_items, selectedItems.size)
|
||||
}
|
||||
|
||||
private fun removeSelected() {
|
||||
if (selectedItems.size > 0)
|
||||
activity?.let { activity ->
|
||||
OKDialog.showConfirmation(activity, rh.gs(R.string.removerecord), getConfirmationText(), Runnable {
|
||||
selectedItems.forEach { therapyEvent ->
|
||||
uel.log(
|
||||
Action.CAREPORTAL_REMOVED, Sources.Treatments, therapyEvent.note,
|
||||
ValueWithUnit.Timestamp(therapyEvent.timestamp),
|
||||
ValueWithUnit.TherapyEventType(therapyEvent.type)
|
||||
)
|
||||
disposable += repository.runTransactionForResult(InvalidateTherapyEventTransaction(therapyEvent.id))
|
||||
.subscribe(
|
||||
{ result -> result.invalidated.forEach { aapsLogger.debug(LTag.DATABASE, "Invalidated therapy event $it") } },
|
||||
{ aapsLogger.error(LTag.DATABASE, "Error while invalidating therapy event", it) }
|
||||
)
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
package info.nightscout.androidaps.activities.fragments
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
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.view.*
|
||||
import android.view.ActionMode
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import dagger.android.support.DaggerFragment
|
||||
|
@ -27,16 +25,17 @@ import info.nightscout.androidaps.extensions.toVisibility
|
|||
import info.nightscout.androidaps.interfaces.ActivePlugin
|
||||
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||
import info.nightscout.shared.logging.AAPSLogger
|
||||
import info.nightscout.shared.logging.LTag
|
||||
import info.nightscout.androidaps.logging.UserEntryLogger
|
||||
import info.nightscout.androidaps.plugins.bus.RxBus
|
||||
import info.nightscout.androidaps.activities.fragments.TreatmentsExtendedBolusesFragment.RecyclerViewAdapter.ExtendedBolusesViewHolder
|
||||
import info.nightscout.androidaps.events.EventTreatmentUpdateGui
|
||||
import info.nightscout.androidaps.utils.DateUtil
|
||||
import info.nightscout.androidaps.utils.FabricPrivacy
|
||||
import info.nightscout.androidaps.utils.T
|
||||
import info.nightscout.androidaps.utils.alertDialogs.OKDialog
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import info.nightscout.androidaps.utils.rx.AapsSchedulers
|
||||
import info.nightscout.shared.logging.LTag
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
import io.reactivex.rxkotlin.plusAssign
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
@ -61,22 +60,28 @@ class TreatmentsExtendedBolusesFragment : DaggerFragment() {
|
|||
|
||||
private var _binding: TreatmentsExtendedbolusFragmentBinding? = null
|
||||
|
||||
// This property is only valid between onCreateView and
|
||||
// onDestroyView.
|
||||
// This property is only valid between onCreateView and onDestroyView.
|
||||
private val binding get() = _binding!!
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?): View =
|
||||
private var selectedItems: MutableList<ExtendedBolus> = mutableListOf()
|
||||
private var showInvalidated = false
|
||||
private var removeActionMode: ActionMode? = null
|
||||
private var toolbar: Toolbar? = null
|
||||
// val TAG = "TreatmentMenu"
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View =
|
||||
TreatmentsExtendedbolusFragmentBinding.inflate(inflater, container, false).also { _binding = it }.root
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
setHasOptionsMenu(true)
|
||||
toolbar = activity?.findViewById(R.id.toolbar)
|
||||
binding.recyclerview.setHasFixedSize(true)
|
||||
binding.recyclerview.layoutManager = LinearLayoutManager(view.context)
|
||||
}
|
||||
|
||||
fun swapAdapter() {
|
||||
val now = System.currentTimeMillis()
|
||||
if (binding.showInvalidated.isChecked)
|
||||
disposable += if (showInvalidated)
|
||||
repository
|
||||
.getExtendedBolusDataIncludingInvalidFromTime(now - millsToThePast, false)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
|
@ -109,6 +114,7 @@ class TreatmentsExtendedBolusesFragment : DaggerFragment() {
|
|||
@Synchronized
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
removeActionMode?.let { it.finish() }
|
||||
binding.recyclerview.adapter = null // avoid leaks
|
||||
_binding = null
|
||||
}
|
||||
|
@ -125,7 +131,7 @@ class TreatmentsExtendedBolusesFragment : DaggerFragment() {
|
|||
holder.binding.ns.visibility = (extendedBolus.interfaceIDs.nightscoutId != null).toVisibility()
|
||||
holder.binding.ph.visibility = (extendedBolus.interfaceIDs.pumpId != null).toVisibility()
|
||||
holder.binding.invalid.visibility = extendedBolus.isValid.not().toVisibility()
|
||||
val sameDayPrevious = position > 0 && dateUtil.isSameDay(extendedBolus.timestamp, extendedBolusList[position-1].timestamp)
|
||||
val sameDayPrevious = position > 0 && dateUtil.isSameDay(extendedBolus.timestamp, extendedBolusList[position - 1].timestamp)
|
||||
holder.binding.date.visibility = sameDayPrevious.not().toVisibility()
|
||||
holder.binding.date.text = dateUtil.dateString(extendedBolus.timestamp)
|
||||
@SuppressLint("SetTextI18n")
|
||||
|
@ -143,41 +149,119 @@ class TreatmentsExtendedBolusesFragment : DaggerFragment() {
|
|||
holder.binding.iob.text = rh.gs(R.string.formatinsulinunits, iob.iob)
|
||||
holder.binding.ratio.text = rh.gs(R.string.pump_basebasalrate, extendedBolus.rate)
|
||||
if (iob.iob != 0.0) holder.binding.iob.setTextColor(rh.gc(R.color.colorActive)) else holder.binding.iob.setTextColor(holder.binding.insulin.currentTextColor)
|
||||
holder.binding.remove.tag = extendedBolus
|
||||
holder.binding.cbRemove.visibility = (extendedBolus.isValid && (removeActionMode != null)).toVisibility()
|
||||
holder.binding.cbRemove.setOnCheckedChangeListener { _, value ->
|
||||
if (value) {
|
||||
selectedItems.add(extendedBolus)
|
||||
} else {
|
||||
selectedItems.remove(extendedBolus)
|
||||
}
|
||||
removeActionMode?.title = rh.gs(R.string.count_selected, selectedItems.size)
|
||||
}
|
||||
val nextTimestamp = if (extendedBolusList.size != position + 1) extendedBolusList[position + 1].timestamp else 0L
|
||||
holder.binding.delimiter.visibility = dateUtil.isSameDay(extendedBolus.timestamp, nextTimestamp).toVisibility()
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = extendedBolusList.size
|
||||
override fun getItemCount() = extendedBolusList.size
|
||||
|
||||
inner class ExtendedBolusesViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||
|
||||
val binding = TreatmentsExtendedbolusItemBinding.bind(itemView)
|
||||
|
||||
init {
|
||||
binding.remove.setOnClickListener { v: View ->
|
||||
val extendedBolus = v.tag as ExtendedBolus
|
||||
context?.let { context ->
|
||||
OKDialog.showConfirmation(context, rh.gs(R.string.removerecord),
|
||||
"""
|
||||
${rh.gs(R.string.extended_bolus)}
|
||||
${rh.gs(R.string.date)}: ${dateUtil.dateAndTimeString(extendedBolus.timestamp)}
|
||||
""".trimIndent(), { _: DialogInterface, _: Int ->
|
||||
uel.log(Action.EXTENDED_BOLUS_REMOVED, Sources.Treatments,
|
||||
ValueWithUnit.Timestamp(extendedBolus.timestamp),
|
||||
ValueWithUnit.Insulin(extendedBolus.amount),
|
||||
ValueWithUnit.UnitPerHour(extendedBolus.rate),
|
||||
ValueWithUnit.Minute(TimeUnit.MILLISECONDS.toMinutes(extendedBolus.duration).toInt()))
|
||||
disposable += repository.runTransactionForResult(InvalidateExtendedBolusTransaction(extendedBolus.id))
|
||||
.subscribe(
|
||||
{ aapsLogger.debug(LTag.DATABASE, "Removed extended bolus $extendedBolus") },
|
||||
{ aapsLogger.error(LTag.DATABASE, "Error while invalidating extended bolus", it) })
|
||||
}, null)
|
||||
}
|
||||
}
|
||||
binding.remove.paintFlags = binding.remove.paintFlags or Paint.UNDERLINE_TEXT_FLAG
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||
inflater.inflate(R.menu.menu_treatments_extended_bolus, menu)
|
||||
super.onCreateOptionsMenu(menu, inflater)
|
||||
}
|
||||
|
||||
override fun onPrepareOptionsMenu(menu: Menu) {
|
||||
menu.findItem(R.id.nav_hide_invalidated)?.isVisible = showInvalidated
|
||||
menu.findItem(R.id.nav_show_invalidated)?.isVisible = !showInvalidated
|
||||
|
||||
return super.onPrepareOptionsMenu(menu)
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
return when (item.itemId) {
|
||||
R.id.nav_remove_items -> {
|
||||
removeActionMode = toolbar?.startActionMode(RemoveActionModeCallback())
|
||||
true
|
||||
}
|
||||
|
||||
R.id.nav_show_invalidated -> {
|
||||
showInvalidated = true
|
||||
rxBus.send(EventTreatmentUpdateGui())
|
||||
true
|
||||
}
|
||||
|
||||
R.id.nav_hide_invalidated -> {
|
||||
showInvalidated = false
|
||||
rxBus.send(EventTreatmentUpdateGui())
|
||||
true
|
||||
}
|
||||
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
inner class RemoveActionModeCallback : ActionMode.Callback {
|
||||
|
||||
override fun onCreateActionMode(mode: ActionMode, menu: Menu?): Boolean {
|
||||
mode.menuInflater.inflate(R.menu.menu_delete_selection, menu)
|
||||
selectedItems = mutableListOf()
|
||||
mode.title = rh.gs(R.string.count_selected, selectedItems.size)
|
||||
binding.recyclerview.adapter?.notifyDataSetChanged()
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onPrepareActionMode(mode: ActionMode?, menu: Menu?) = false
|
||||
|
||||
override fun onActionItemClicked(mode: ActionMode, item: MenuItem): Boolean {
|
||||
return when (item.itemId) {
|
||||
R.id.remove_selected -> {
|
||||
removeSelected()
|
||||
mode.finish()
|
||||
true
|
||||
}
|
||||
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroyActionMode(mode: ActionMode?) {
|
||||
removeActionMode = null
|
||||
binding.recyclerview.adapter?.notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
|
||||
private fun getConfirmationText(): String {
|
||||
if (selectedItems.size == 1) {
|
||||
return rh.gs(R.string.extended_bolus) + "\n" +
|
||||
"${rh.gs(R.string.date)}: ${dateUtil.dateAndTimeString(selectedItems.first().timestamp)}"
|
||||
}
|
||||
return rh.gs(R.string.confirm_remove_multiple_items, selectedItems.size)
|
||||
}
|
||||
|
||||
private fun removeSelected() {
|
||||
if (selectedItems.size > 0)
|
||||
activity?.let { activity ->
|
||||
OKDialog.showConfirmation(activity, rh.gs(R.string.removerecord), getConfirmationText(), Runnable {
|
||||
selectedItems.forEach { extendedBolus ->
|
||||
uel.log(
|
||||
Action.EXTENDED_BOLUS_REMOVED, Sources.Treatments,
|
||||
ValueWithUnit.Timestamp(extendedBolus.timestamp),
|
||||
ValueWithUnit.Insulin(extendedBolus.amount),
|
||||
ValueWithUnit.UnitPerHour(extendedBolus.rate),
|
||||
ValueWithUnit.Minute(TimeUnit.MILLISECONDS.toMinutes(extendedBolus.duration).toInt())
|
||||
)
|
||||
disposable += repository.runTransactionForResult(InvalidateExtendedBolusTransaction(extendedBolus.id))
|
||||
.subscribe(
|
||||
{ aapsLogger.debug(LTag.DATABASE, "Removed extended bolus $extendedBolus") },
|
||||
{ aapsLogger.error(LTag.DATABASE, "Error while invalidating extended bolus", it) })
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,9 +2,9 @@ package info.nightscout.androidaps.activities.fragments
|
|||
|
||||
import android.graphics.Paint
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.*
|
||||
import android.view.ActionMode
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import dagger.android.support.DaggerFragment
|
||||
|
@ -65,9 +65,12 @@ class TreatmentsProfileSwitchFragment : DaggerFragment() {
|
|||
private val disposable = CompositeDisposable()
|
||||
|
||||
private val millsToThePast = T.days(30).msecs()
|
||||
private var selectedItems: MutableList<ProfileSealed> = mutableListOf()
|
||||
private var showInvalidated = false
|
||||
private var removeActionMode: ActionMode? = null
|
||||
private var toolbar: Toolbar? = null
|
||||
|
||||
// This property is only valid between onCreateView and
|
||||
// onDestroyView.
|
||||
// This property is only valid between onCreateView and onDestroyView.
|
||||
private val binding get() = _binding!!
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View =
|
||||
|
@ -75,36 +78,34 @@ class TreatmentsProfileSwitchFragment : DaggerFragment() {
|
|||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
setHasOptionsMenu(true)
|
||||
toolbar = activity?.findViewById(R.id.toolbar)
|
||||
binding.recyclerview.setHasFixedSize(true)
|
||||
binding.recyclerview.layoutManager = LinearLayoutManager(view.context)
|
||||
}
|
||||
|
||||
binding.refreshFromNightscout.setOnClickListener {
|
||||
activity?.let { activity ->
|
||||
OKDialog.showConfirmation(activity, rh.gs(R.string.refresheventsfromnightscout) + "?") {
|
||||
uel.log(Action.TREATMENTS_NS_REFRESH, Sources.Treatments)
|
||||
disposable +=
|
||||
Completable.fromAction {
|
||||
repository.deleteAllEffectiveProfileSwitches()
|
||||
repository.deleteAllProfileSwitches()
|
||||
}
|
||||
.subscribeOn(aapsSchedulers.io)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribeBy(
|
||||
onError = { aapsLogger.error("Error removing entries", it) },
|
||||
onComplete = {
|
||||
rxBus.send(EventProfileSwitchChanged())
|
||||
rxBus.send(EventEffectiveProfileSwitchChanged(0L))
|
||||
rxBus.send(EventNewHistoryData(0, false))
|
||||
}
|
||||
)
|
||||
rxBus.send(EventNSClientRestart())
|
||||
}
|
||||
private fun refreshFromNightscout() {
|
||||
activity?.let { activity ->
|
||||
OKDialog.showConfirmation(activity, rh.gs(R.string.refresheventsfromnightscout) + "?") {
|
||||
uel.log(Action.TREATMENTS_NS_REFRESH, Sources.Treatments)
|
||||
disposable +=
|
||||
Completable.fromAction {
|
||||
repository.deleteAllEffectiveProfileSwitches()
|
||||
repository.deleteAllProfileSwitches()
|
||||
}
|
||||
.subscribeOn(aapsSchedulers.io)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribeBy(
|
||||
onError = { aapsLogger.error("Error removing entries", it) },
|
||||
onComplete = {
|
||||
rxBus.send(EventProfileSwitchChanged())
|
||||
rxBus.send(EventEffectiveProfileSwitchChanged(0L))
|
||||
rxBus.send(EventNewHistoryData(0, false))
|
||||
}
|
||||
)
|
||||
rxBus.send(EventNSClientRestart())
|
||||
}
|
||||
}
|
||||
if (!sp.getBoolean(R.string.key_ns_receive_profile_switch, false) || !buildHelper.isEngineeringMode()) binding.refreshFromNightscout.visibility = View.GONE
|
||||
binding.showInvalidated.setOnCheckedChangeListener { _, _ ->
|
||||
rxBus.send(EventTreatmentUpdateGui())
|
||||
}
|
||||
}
|
||||
|
||||
private fun profileSwitchWithInvalid(now: Long) = repository
|
||||
|
@ -126,23 +127,23 @@ class TreatmentsProfileSwitchFragment : DaggerFragment() {
|
|||
fun swapAdapter() {
|
||||
val now = System.currentTimeMillis()
|
||||
|
||||
if (binding.showInvalidated.isChecked)
|
||||
disposable += profileSwitchWithInvalid(now)
|
||||
.zipWith(effectiveProfileSwitchWithInvalid(now)) { first, second -> first + second }
|
||||
.map { ml -> ml.sortedByDescending { it.timestamp } }
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe { list ->
|
||||
binding.recyclerview.swapAdapter(RecyclerProfileViewAdapter(list), true)
|
||||
}
|
||||
else
|
||||
disposable += profileSwitches(now)
|
||||
.zipWith(effectiveProfileSwitches(now)) { first, second -> first + second }
|
||||
.map { ml -> ml.sortedByDescending { it.timestamp } }
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe { list ->
|
||||
binding.recyclerview.swapAdapter(RecyclerProfileViewAdapter(list), true)
|
||||
}
|
||||
|
||||
disposable +=
|
||||
if (showInvalidated)
|
||||
profileSwitchWithInvalid(now)
|
||||
.zipWith(effectiveProfileSwitchWithInvalid(now)) { first, second -> first + second }
|
||||
.map { ml -> ml.sortedByDescending { it.timestamp } }
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe { list ->
|
||||
binding.recyclerview.swapAdapter(RecyclerProfileViewAdapter(list), true)
|
||||
}
|
||||
else
|
||||
profileSwitches(now)
|
||||
.zipWith(effectiveProfileSwitches(now)) { first, second -> first + second }
|
||||
.map { ml -> ml.sortedByDescending { it.timestamp } }
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe { list ->
|
||||
binding.recyclerview.swapAdapter(RecyclerProfileViewAdapter(list), true)
|
||||
}
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
|
@ -168,6 +169,7 @@ class TreatmentsProfileSwitchFragment : DaggerFragment() {
|
|||
@Synchronized
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
removeActionMode?.let { it.finish() }
|
||||
binding.recyclerview.adapter = null // avoid leaks
|
||||
_binding = null
|
||||
}
|
||||
|
@ -189,13 +191,20 @@ class TreatmentsProfileSwitchFragment : DaggerFragment() {
|
|||
holder.binding.name.text = if (profileSwitch is ProfileSealed.PS) profileSwitch.value.getCustomizedName() else if (profileSwitch is ProfileSealed.EPS) profileSwitch.value.originalCustomizedName else ""
|
||||
if (profileSwitch.isInProgress(dateUtil)) holder.binding.date.setTextColor(rh.gc(R.color.colorActive))
|
||||
else holder.binding.date.setTextColor(holder.binding.duration.currentTextColor)
|
||||
holder.binding.remove.tag = profileSwitch
|
||||
holder.binding.clone.tag = profileSwitch
|
||||
holder.binding.name.tag = profileSwitch
|
||||
holder.binding.date.tag = profileSwitch
|
||||
holder.binding.invalid.visibility = profileSwitch.isValid.not().toVisibility()
|
||||
holder.binding.duration.visibility = (profileSwitch.duration != 0L && profileSwitch.duration != null).toVisibility()
|
||||
holder.binding.remove.visibility = (profileSwitch is ProfileSealed.PS).toVisibility()
|
||||
holder.binding.cbRemove.visibility = (removeActionMode != null && profileSwitch is ProfileSealed.PS).toVisibility()
|
||||
holder.binding.cbRemove.setOnCheckedChangeListener { _, value ->
|
||||
if (value) {
|
||||
selectedItems.add(profileSwitch)
|
||||
} else {
|
||||
selectedItems.remove(profileSwitch)
|
||||
}
|
||||
removeActionMode?.title = rh.gs(R.string.count_selected, selectedItems.size)
|
||||
}
|
||||
holder.binding.clone.visibility = (profileSwitch is ProfileSealed.PS).toVisibility()
|
||||
holder.binding.spacer.visibility = (profileSwitch is ProfileSealed.PS).toVisibility()
|
||||
holder.binding.root.setBackgroundColor(rh.gc(if (profileSwitch is ProfileSealed.PS) R.color.defaultbackground else R.color.list_delimiter))
|
||||
|
@ -203,47 +212,39 @@ class TreatmentsProfileSwitchFragment : DaggerFragment() {
|
|||
holder.binding.delimiter.visibility = dateUtil.isSameDay(profileSwitch.timestamp, nextTimestamp).toVisibility()
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
return profileSwitchList.size
|
||||
}
|
||||
override fun getItemCount() = profileSwitchList.size
|
||||
|
||||
inner class ProfileSwitchViewHolder internal constructor(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||
|
||||
val binding = TreatmentsProfileswitchItemBinding.bind(itemView)
|
||||
|
||||
init {
|
||||
binding.remove.setOnClickListener { view ->
|
||||
val profileSwitch = view.tag as ProfileSealed.PS
|
||||
activity?.let { activity ->
|
||||
OKDialog.showConfirmation(activity, rh.gs(R.string.removerecord),
|
||||
rh.gs(R.string.careportal_profileswitch) + ": " + profileSwitch.profileName +
|
||||
"\n" + rh.gs(R.string.date) + ": " + dateUtil.dateAndTimeString(profileSwitch.timestamp), Runnable {
|
||||
uel.log(Action.PROFILE_SWITCH_REMOVED, Sources.Treatments, profileSwitch.profileName,
|
||||
ValueWithUnit.Timestamp(profileSwitch.timestamp))
|
||||
disposable += repository.runTransactionForResult(InvalidateProfileSwitchTransaction(profileSwitch.id))
|
||||
.subscribe(
|
||||
{ result -> result.invalidated.forEach { aapsLogger.debug(LTag.DATABASE, "Invalidated ProfileSwitch $it") } },
|
||||
{ aapsLogger.error(LTag.DATABASE, "Error while invalidating ProfileSwitch", it) }
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
binding.clone.setOnClickListener {
|
||||
activity?.let { activity ->
|
||||
val profileSwitch = (it.tag as ProfileSealed.PS).value
|
||||
val profileSealed = it.tag as ProfileSealed
|
||||
OKDialog.showConfirmation(activity, rh.gs(R.string.careportal_profileswitch), rh.gs(R.string.copytolocalprofile) + "\n" + profileSwitch.getCustomizedName() + "\n" + dateUtil.dateAndTimeString(profileSwitch.timestamp), Runnable {
|
||||
uel.log(Action.PROFILE_SWITCH_CLONED, Sources.Treatments,
|
||||
profileSwitch.getCustomizedName() + " " + dateUtil.dateAndTimeString(profileSwitch.timestamp).replace(".", "_"),
|
||||
ValueWithUnit.Timestamp(profileSwitch.timestamp),
|
||||
ValueWithUnit.SimpleString(profileSwitch.profileName))
|
||||
val nonCustomized = profileSealed.convertToNonCustomizedProfile(dateUtil)
|
||||
localProfilePlugin.addProfile(localProfilePlugin.copyFrom(nonCustomized, profileSwitch.getCustomizedName() + " " + dateUtil.dateAndTimeString(profileSwitch.timestamp).replace(".", "_")))
|
||||
rxBus.send(EventLocalProfileChanged())
|
||||
})
|
||||
OKDialog.showConfirmation(
|
||||
activity,
|
||||
rh.gs(R.string.careportal_profileswitch),
|
||||
rh.gs(R.string.copytolocalprofile) + "\n" + profileSwitch.getCustomizedName() + "\n" + dateUtil.dateAndTimeString(profileSwitch.timestamp),
|
||||
Runnable {
|
||||
uel.log(
|
||||
Action.PROFILE_SWITCH_CLONED, Sources.Treatments,
|
||||
profileSwitch.getCustomizedName() + " " + dateUtil.dateAndTimeString(profileSwitch.timestamp).replace(".", "_"),
|
||||
ValueWithUnit.Timestamp(profileSwitch.timestamp),
|
||||
ValueWithUnit.SimpleString(profileSwitch.profileName)
|
||||
)
|
||||
val nonCustomized = profileSealed.convertToNonCustomizedProfile(dateUtil)
|
||||
localProfilePlugin.addProfile(
|
||||
localProfilePlugin.copyFrom(
|
||||
nonCustomized,
|
||||
profileSwitch.getCustomizedName() + " " + dateUtil.dateAndTimeString(profileSwitch.timestamp).replace(".", "_")
|
||||
)
|
||||
)
|
||||
rxBus.send(EventLocalProfileChanged())
|
||||
})
|
||||
}
|
||||
}
|
||||
binding.remove.paintFlags = binding.remove.paintFlags or Paint.UNDERLINE_TEXT_FLAG
|
||||
binding.clone.paintFlags = binding.clone.paintFlags or Paint.UNDERLINE_TEXT_FLAG
|
||||
binding.name.setOnClickListener {
|
||||
ProfileViewerDialog().also { pvd ->
|
||||
|
@ -266,4 +267,103 @@ class TreatmentsProfileSwitchFragment : DaggerFragment() {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||
inflater.inflate(R.menu.menu_treatments_profile_switch, menu)
|
||||
super.onCreateOptionsMenu(menu, inflater)
|
||||
}
|
||||
|
||||
override fun onPrepareOptionsMenu(menu: Menu) {
|
||||
menu.findItem(R.id.nav_hide_invalidated)?.isVisible = showInvalidated
|
||||
menu.findItem(R.id.nav_show_invalidated)?.isVisible = !showInvalidated
|
||||
val nsUploadOnly = !sp.getBoolean(R.string.key_ns_receive_profile_switch, false) || !buildHelper.isEngineeringMode()
|
||||
menu.findItem(R.id.nav_refresh_ns)?.isVisible = !nsUploadOnly
|
||||
|
||||
return super.onPrepareOptionsMenu(menu)
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
return when (item.itemId) {
|
||||
R.id.nav_remove_items -> {
|
||||
removeActionMode = toolbar?.startActionMode(RemoveActionModeCallback())
|
||||
true
|
||||
}
|
||||
|
||||
R.id.nav_show_invalidated -> {
|
||||
showInvalidated = true
|
||||
rxBus.send(EventTreatmentUpdateGui())
|
||||
true
|
||||
}
|
||||
|
||||
R.id.nav_hide_invalidated -> {
|
||||
showInvalidated = false
|
||||
rxBus.send(EventTreatmentUpdateGui())
|
||||
true
|
||||
}
|
||||
|
||||
R.id.nav_refresh_ns -> {
|
||||
refreshFromNightscout()
|
||||
true
|
||||
}
|
||||
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
inner class RemoveActionModeCallback : ActionMode.Callback {
|
||||
|
||||
override fun onCreateActionMode(mode: ActionMode, menu: Menu?): Boolean {
|
||||
mode.menuInflater.inflate(R.menu.menu_delete_selection, menu)
|
||||
selectedItems = mutableListOf()
|
||||
mode.title = rh.gs(R.string.count_selected, selectedItems.size)
|
||||
binding.recyclerview.adapter?.notifyDataSetChanged()
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onPrepareActionMode(mode: ActionMode?, menu: Menu?) = false
|
||||
|
||||
override fun onActionItemClicked(mode: ActionMode, item: MenuItem): Boolean {
|
||||
return when (item.itemId) {
|
||||
R.id.remove_selected -> {
|
||||
removeSelected()
|
||||
mode.finish()
|
||||
true
|
||||
}
|
||||
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroyActionMode(mode: ActionMode?) {
|
||||
removeActionMode = null
|
||||
binding.recyclerview.adapter?.notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
|
||||
private fun getConfirmationText(): String {
|
||||
if (selectedItems.size == 1) {
|
||||
val profileSwitch = selectedItems.first()
|
||||
return rh.gs(R.string.careportal_profileswitch) + ": " + profileSwitch.profileName + "\n" + rh.gs(R.string.date) + ": " + dateUtil.dateAndTimeString(profileSwitch.timestamp)
|
||||
}
|
||||
return rh.gs(R.string.confirm_remove_multiple_items, selectedItems.size)
|
||||
}
|
||||
|
||||
private fun removeSelected() {
|
||||
if (selectedItems.size > 0)
|
||||
activity?.let { activity ->
|
||||
OKDialog.showConfirmation(activity, rh.gs(R.string.removerecord), getConfirmationText(), Runnable {
|
||||
selectedItems.forEach { profileSwitch ->
|
||||
uel.log(
|
||||
Action.PROFILE_SWITCH_REMOVED, Sources.Treatments, profileSwitch.profileName,
|
||||
ValueWithUnit.Timestamp(profileSwitch.timestamp)
|
||||
)
|
||||
disposable += repository.runTransactionForResult(InvalidateProfileSwitchTransaction(profileSwitch.id))
|
||||
.subscribe(
|
||||
{ result -> result.invalidated.forEach { aapsLogger.debug(LTag.DATABASE, "Invalidated ProfileSwitch $it") } },
|
||||
{ aapsLogger.error(LTag.DATABASE, "Error while invalidating ProfileSwitch", it) }
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,9 @@
|
|||
package info.nightscout.androidaps.activities.fragments
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
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.view.*
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import dagger.android.support.DaggerFragment
|
||||
|
@ -30,6 +27,8 @@ import info.nightscout.androidaps.plugins.bus.RxBus
|
|||
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientRestart
|
||||
import info.nightscout.androidaps.events.EventTreatmentUpdateGui
|
||||
import info.nightscout.androidaps.activities.fragments.TreatmentsTempTargetFragment.RecyclerViewAdapter.TempTargetsViewHolder
|
||||
import info.nightscout.androidaps.events.EventEffectiveProfileSwitchChanged
|
||||
import info.nightscout.androidaps.events.EventProfileSwitchChanged
|
||||
import info.nightscout.androidaps.utils.DateUtil
|
||||
import info.nightscout.androidaps.utils.FabricPrivacy
|
||||
import info.nightscout.androidaps.utils.T
|
||||
|
@ -40,6 +39,7 @@ import info.nightscout.androidaps.extensions.friendlyDescription
|
|||
import info.nightscout.androidaps.extensions.highValueToUnitsToString
|
||||
import info.nightscout.androidaps.extensions.lowValueToUnitsToString
|
||||
import info.nightscout.androidaps.extensions.toVisibility
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventNewHistoryData
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import info.nightscout.androidaps.utils.rx.AapsSchedulers
|
||||
import info.nightscout.shared.sharedPreferences.SP
|
||||
|
@ -68,11 +68,14 @@ class TreatmentsTempTargetFragment : DaggerFragment() {
|
|||
private val disposable = CompositeDisposable()
|
||||
|
||||
private val millsToThePast = T.days(30).msecs()
|
||||
private var selectedItems: MutableList<TemporaryTarget> = mutableListOf()
|
||||
private var showInvalidated = false
|
||||
private var toolbar: Toolbar? = null
|
||||
private var removeActionMode: ActionMode? = null
|
||||
|
||||
private var _binding: TreatmentsTemptargetFragmentBinding? = null
|
||||
|
||||
// This property is only valid between onCreateView and
|
||||
// onDestroyView.
|
||||
// This property is only valid between onCreateView and onDestroyView.
|
||||
private val binding get() = _binding!!
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View =
|
||||
|
@ -80,42 +83,48 @@ class TreatmentsTempTargetFragment : DaggerFragment() {
|
|||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
binding.recyclerview.setHasFixedSize(true)
|
||||
toolbar = activity?.findViewById(R.id.toolbar)
|
||||
setHasOptionsMenu(true)
|
||||
binding.recyclerview.layoutManager = LinearLayoutManager(view.context)
|
||||
binding.refreshFromNightscout.setOnClickListener {
|
||||
context?.let { context ->
|
||||
OKDialog.showConfirmation(context, rh.gs(R.string.refresheventsfromnightscout) + " ?", {
|
||||
uel.log(Action.TT_NS_REFRESH, Sources.Treatments)
|
||||
disposable += Completable.fromAction { repository.deleteAllTempTargetEntries() }
|
||||
}
|
||||
|
||||
private fun refreshFromNightscout() {
|
||||
activity?.let { activity ->
|
||||
OKDialog.showConfirmation(activity, rh.gs(R.string.refresheventsfromnightscout) + "?") {
|
||||
uel.log(Action.TREATMENTS_NS_REFRESH, Sources.Treatments)
|
||||
disposable +=
|
||||
Completable.fromAction {
|
||||
repository.deleteAllEffectiveProfileSwitches()
|
||||
repository.deleteAllProfileSwitches()
|
||||
}
|
||||
.subscribeOn(aapsSchedulers.io)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribeBy(
|
||||
onError = { aapsLogger.error("Error removing entries", it) },
|
||||
onComplete = { rxBus.send(EventTempTargetChange()) }
|
||||
onComplete = {
|
||||
rxBus.send(EventProfileSwitchChanged())
|
||||
rxBus.send(EventEffectiveProfileSwitchChanged(0L))
|
||||
rxBus.send(EventNewHistoryData(0, false))
|
||||
}
|
||||
)
|
||||
|
||||
rxBus.send(EventNSClientRestart())
|
||||
})
|
||||
rxBus.send(EventNSClientRestart())
|
||||
}
|
||||
}
|
||||
val nsUploadOnly = !sp.getBoolean(R.string.key_ns_receive_temp_target, false) || !buildHelper.isEngineeringMode()
|
||||
if (nsUploadOnly) binding.refreshFromNightscout.visibility = View.INVISIBLE
|
||||
binding.showInvalidated.setOnCheckedChangeListener { _, _ ->
|
||||
rxBus.send(EventTreatmentUpdateGui())
|
||||
}
|
||||
}
|
||||
|
||||
fun swapAdapter() {
|
||||
val now = System.currentTimeMillis()
|
||||
if (binding.showInvalidated.isChecked)
|
||||
repository
|
||||
.getTemporaryTargetDataIncludingInvalidFromTime(now - millsToThePast, false)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe { list -> binding.recyclerview.swapAdapter(RecyclerViewAdapter(list), true) }
|
||||
else
|
||||
repository
|
||||
.getTemporaryTargetDataFromTime(now - millsToThePast, false)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe { list -> binding.recyclerview.swapAdapter(RecyclerViewAdapter(list), true) }
|
||||
disposable +=
|
||||
if (showInvalidated)
|
||||
repository
|
||||
.getTemporaryTargetDataIncludingInvalidFromTime(now - millsToThePast, false)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe { list -> binding.recyclerview.swapAdapter(RecyclerViewAdapter(list), true) }
|
||||
else
|
||||
repository
|
||||
.getTemporaryTargetDataFromTime(now - millsToThePast, false)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe { list -> binding.recyclerview.swapAdapter(RecyclerViewAdapter(list), true) }
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
|
@ -145,6 +154,7 @@ class TreatmentsTempTargetFragment : DaggerFragment() {
|
|||
@Synchronized
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
removeActionMode?.let { it.finish() }
|
||||
binding.recyclerview.adapter = null // avoid leaks
|
||||
_binding = null
|
||||
}
|
||||
|
@ -163,8 +173,16 @@ class TreatmentsTempTargetFragment : DaggerFragment() {
|
|||
val tempTarget = tempTargetList[position]
|
||||
holder.binding.ns.visibility = (tempTarget.interfaceIDs.nightscoutId != null).toVisibility()
|
||||
holder.binding.invalid.visibility = tempTarget.isValid.not().toVisibility()
|
||||
holder.binding.remove.visibility = tempTarget.isValid.toVisibility()
|
||||
val sameDayPrevious = position > 0 && dateUtil.isSameDay(tempTarget.timestamp, tempTargetList[position-1].timestamp)
|
||||
holder.binding.cbRemove.visibility = (tempTarget.isValid && (removeActionMode != null)).toVisibility()
|
||||
holder.binding.cbRemove.setOnCheckedChangeListener { _, value ->
|
||||
if (value) {
|
||||
selectedItems.add(tempTarget)
|
||||
} else {
|
||||
selectedItems.remove(tempTarget)
|
||||
}
|
||||
removeActionMode?.title = rh.gs(R.string.count_selected, selectedItems.size)
|
||||
}
|
||||
val sameDayPrevious = position > 0 && dateUtil.isSameDay(tempTarget.timestamp, tempTargetList[position - 1].timestamp)
|
||||
holder.binding.date.visibility = sameDayPrevious.not().toVisibility()
|
||||
holder.binding.date.text = dateUtil.dateString(tempTarget.timestamp)
|
||||
holder.binding.time.text = dateUtil.timeRangeString(tempTarget.timestamp, tempTarget.end)
|
||||
|
@ -177,43 +195,123 @@ class TreatmentsTempTargetFragment : DaggerFragment() {
|
|||
tempTarget.id == currentlyActiveTarget?.id -> rh.gc(R.color.colorActive)
|
||||
tempTarget.timestamp > dateUtil.now() -> rh.gc(R.color.colorScheduled)
|
||||
else -> holder.binding.reasonColon.currentTextColor
|
||||
})
|
||||
holder.binding.remove.tag = tempTarget
|
||||
}
|
||||
)
|
||||
val nextTimestamp = if (tempTargetList.size != position + 1) tempTargetList[position + 1].timestamp else 0L
|
||||
holder.binding.delimiter.visibility = dateUtil.isSameDay(tempTarget.timestamp, nextTimestamp).toVisibility()
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = tempTargetList.size
|
||||
override fun getItemCount() = tempTargetList.size
|
||||
|
||||
inner class TempTargetsViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
||||
|
||||
val binding = TreatmentsTemptargetItemBinding.bind(view)
|
||||
|
||||
init {
|
||||
binding.remove.setOnClickListener { v: View ->
|
||||
val tempTarget = v.tag as TemporaryTarget
|
||||
context?.let { context ->
|
||||
OKDialog.showConfirmation(context, rh.gs(R.string.removerecord),
|
||||
"""
|
||||
${rh.gs(R.string.careportal_temporarytarget)}: ${tempTarget.friendlyDescription(profileFunction.getUnits(), rh)}
|
||||
${dateUtil.dateAndTimeString(tempTarget.timestamp)}
|
||||
""".trimIndent(),
|
||||
{ _: DialogInterface?, _: Int ->
|
||||
uel.log(Action.TT_REMOVED, Sources.Treatments,
|
||||
ValueWithUnit.Timestamp(tempTarget.timestamp),
|
||||
ValueWithUnit.TherapyEventTTReason(tempTarget.reason),
|
||||
ValueWithUnit.Mgdl(tempTarget.lowTarget),
|
||||
ValueWithUnit.Mgdl(tempTarget.highTarget).takeIf { tempTarget.lowTarget != tempTarget.highTarget },
|
||||
ValueWithUnit.Minute(TimeUnit.MILLISECONDS.toMinutes(tempTarget.duration).toInt()))
|
||||
disposable += repository.runTransactionForResult(InvalidateTemporaryTargetTransaction(tempTarget.id))
|
||||
.subscribe(
|
||||
{ aapsLogger.debug(LTag.DATABASE, "Removed temp target $tempTarget") },
|
||||
{ aapsLogger.error(LTag.DATABASE, "Error while invalidating temporary target", it) })
|
||||
}, null)
|
||||
}
|
||||
}
|
||||
binding.remove.paintFlags = binding.remove.paintFlags or Paint.UNDERLINE_TEXT_FLAG
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun removeSelected() {
|
||||
// TODO check if item should not be delete val profile = profileFunction.getProfile(dateUtil.now()) == null
|
||||
if (selectedItems.size > 0)
|
||||
activity?.let { activity ->
|
||||
OKDialog.showConfirmation(activity, rh.gs(R.string.removerecord), getConfirmationText(), Runnable {
|
||||
selectedItems.forEach { tempTarget ->
|
||||
uel.log(
|
||||
Action.TT_REMOVED, Sources.Treatments,
|
||||
ValueWithUnit.Timestamp(tempTarget.timestamp),
|
||||
ValueWithUnit.TherapyEventTTReason(tempTarget.reason),
|
||||
ValueWithUnit.Mgdl(tempTarget.lowTarget),
|
||||
ValueWithUnit.Mgdl(tempTarget.highTarget).takeIf { tempTarget.lowTarget != tempTarget.highTarget },
|
||||
ValueWithUnit.Minute(TimeUnit.MILLISECONDS.toMinutes(tempTarget.duration).toInt())
|
||||
)
|
||||
disposable += repository.runTransactionForResult(InvalidateTemporaryTargetTransaction(tempTarget.id))
|
||||
.subscribe(
|
||||
{ aapsLogger.debug(LTag.DATABASE, "Removed temp target $tempTarget") },
|
||||
{ aapsLogger.error(LTag.DATABASE, "Error while invalidating temporary target", it) })
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||
inflater.inflate(R.menu.menu_treatments_temp_target, menu)
|
||||
super.onCreateOptionsMenu(menu, inflater)
|
||||
}
|
||||
|
||||
override fun onPrepareOptionsMenu(menu: Menu) {
|
||||
menu.findItem(R.id.nav_hide_invalidated)?.isVisible = showInvalidated
|
||||
menu.findItem(R.id.nav_show_invalidated)?.isVisible = !showInvalidated
|
||||
val nsUploadOnly = !sp.getBoolean(R.string.key_ns_receive_temp_target, false) || !buildHelper.isEngineeringMode()
|
||||
menu.findItem(R.id.nav_refresh_ns)?.isVisible = !nsUploadOnly
|
||||
|
||||
return super.onPrepareOptionsMenu(menu)
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
return when (item.itemId) {
|
||||
R.id.nav_remove_items -> {
|
||||
removeActionMode = toolbar?.startActionMode(RemoveActionModeCallback())
|
||||
true
|
||||
}
|
||||
|
||||
R.id.nav_show_invalidated -> {
|
||||
showInvalidated = true
|
||||
rxBus.send(EventTreatmentUpdateGui())
|
||||
true
|
||||
}
|
||||
|
||||
R.id.nav_hide_invalidated -> {
|
||||
showInvalidated = false
|
||||
rxBus.send(EventTreatmentUpdateGui())
|
||||
true
|
||||
}
|
||||
|
||||
R.id.nav_refresh_ns -> {
|
||||
refreshFromNightscout()
|
||||
true
|
||||
}
|
||||
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
inner class RemoveActionModeCallback : ActionMode.Callback {
|
||||
|
||||
override fun onCreateActionMode(mode: ActionMode, menu: Menu?): Boolean {
|
||||
mode.menuInflater.inflate(R.menu.menu_delete_selection, menu)
|
||||
selectedItems = mutableListOf()
|
||||
mode.title = rh.gs(R.string.count_selected, selectedItems.size)
|
||||
binding.recyclerview.adapter?.notifyDataSetChanged()
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onPrepareActionMode(mode: ActionMode?, menu: Menu?) = false
|
||||
|
||||
override fun onActionItemClicked(mode: ActionMode, item: MenuItem): Boolean {
|
||||
return when (item.itemId) {
|
||||
R.id.remove_selected -> {
|
||||
removeSelected()
|
||||
mode.finish()
|
||||
true
|
||||
}
|
||||
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroyActionMode(mode: ActionMode?) {
|
||||
removeActionMode = null
|
||||
binding.recyclerview.adapter?.notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
|
||||
private fun getConfirmationText(): String {
|
||||
if (selectedItems.size == 1) {
|
||||
val tempTarget = selectedItems.first()
|
||||
return "${rh.gs(R.string.careportal_temporarytarget)}: ${tempTarget.friendlyDescription(profileFunction.getUnits(), rh)}\n" +
|
||||
dateUtil.dateAndTimeString(tempTarget.timestamp)
|
||||
}
|
||||
return rh.gs(R.string.confirm_remove_multiple_items, selectedItems.size)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,11 +1,8 @@
|
|||
package info.nightscout.androidaps.activities.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.view.*
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import dagger.android.support.DaggerFragment
|
||||
|
@ -36,6 +33,7 @@ import info.nightscout.shared.logging.LTag
|
|||
import info.nightscout.androidaps.logging.UserEntryLogger
|
||||
import info.nightscout.androidaps.plugins.bus.RxBus
|
||||
import info.nightscout.androidaps.activities.fragments.TreatmentsTemporaryBasalsFragment.RecyclerViewAdapter.TempBasalsViewHolder
|
||||
import info.nightscout.androidaps.events.EventTreatmentUpdateGui
|
||||
import info.nightscout.androidaps.utils.DateUtil
|
||||
import info.nightscout.androidaps.utils.FabricPrivacy
|
||||
import info.nightscout.androidaps.utils.T
|
||||
|
@ -66,9 +64,12 @@ class TreatmentsTemporaryBasalsFragment : DaggerFragment() {
|
|||
private var _binding: TreatmentsTempbasalsFragmentBinding? = null
|
||||
|
||||
private val millsToThePast = T.days(30).msecs()
|
||||
private var selectedItems: MutableList<TemporaryBasal> = mutableListOf()
|
||||
private var showInvalidated = false
|
||||
private var toolbar: Toolbar? = null
|
||||
private var removeActionMode: ActionMode? = null
|
||||
|
||||
// This property is only valid between onCreateView and
|
||||
// onDestroyView.
|
||||
// This property is only valid between onCreateView and onDestroyView.
|
||||
private val binding get() = _binding!!
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View =
|
||||
|
@ -76,6 +77,8 @@ class TreatmentsTemporaryBasalsFragment : DaggerFragment() {
|
|||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
toolbar = activity?.findViewById(R.id.toolbar)
|
||||
setHasOptionsMenu(true)
|
||||
binding.recyclerview.setHasFixedSize(true)
|
||||
binding.recyclerview.layoutManager = LinearLayoutManager(view.context)
|
||||
}
|
||||
|
@ -98,7 +101,7 @@ class TreatmentsTemporaryBasalsFragment : DaggerFragment() {
|
|||
val now = System.currentTimeMillis()
|
||||
disposable +=
|
||||
if (activePlugin.activePump.isFakingTempsByExtendedBoluses) {
|
||||
if (binding.showInvalidated.isChecked)
|
||||
if (showInvalidated)
|
||||
tempBasalsWithInvalid(now)
|
||||
.zipWith(extendedBolusesWithInvalid(now)) { first, second -> first + second }
|
||||
.map { list -> list.filterNotNull() }
|
||||
|
@ -113,7 +116,7 @@ class TreatmentsTemporaryBasalsFragment : DaggerFragment() {
|
|||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe { list -> binding.recyclerview.swapAdapter(RecyclerViewAdapter(list), true) }
|
||||
} else {
|
||||
if (binding.showInvalidated.isChecked)
|
||||
if (showInvalidated)
|
||||
tempBasalsWithInvalid(now)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe { list -> binding.recyclerview.swapAdapter(RecyclerViewAdapter(list), true) }
|
||||
|
@ -150,6 +153,7 @@ class TreatmentsTemporaryBasalsFragment : DaggerFragment() {
|
|||
@Synchronized
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
removeActionMode?.let { it.finish() }
|
||||
binding.recyclerview.adapter = null // avoid leaks
|
||||
_binding = null
|
||||
}
|
||||
|
@ -164,7 +168,7 @@ class TreatmentsTemporaryBasalsFragment : DaggerFragment() {
|
|||
holder.binding.ns.visibility = (tempBasal.interfaceIDs.nightscoutId != null).toVisibility()
|
||||
holder.binding.invalid.visibility = tempBasal.isValid.not().toVisibility()
|
||||
holder.binding.ph.visibility = (tempBasal.interfaceIDs.pumpId != null).toVisibility()
|
||||
val sameDayPrevious = position > 0 && dateUtil.isSameDay(tempBasal.timestamp, tempBasalList[position-1].timestamp)
|
||||
val sameDayPrevious = position > 0 && dateUtil.isSameDay(tempBasal.timestamp, tempBasalList[position - 1].timestamp)
|
||||
holder.binding.date.visibility = sameDayPrevious.not().toVisibility()
|
||||
holder.binding.date.text = dateUtil.dateString(tempBasal.timestamp)
|
||||
if (tempBasal.isInProgress) {
|
||||
|
@ -187,62 +191,144 @@ class TreatmentsTemporaryBasalsFragment : DaggerFragment() {
|
|||
holder.binding.emulatedSuspendFlag.visibility = (tempBasal.type == TemporaryBasal.Type.EMULATED_PUMP_SUSPEND).toVisibility()
|
||||
holder.binding.superBolusFlag.visibility = (tempBasal.type == TemporaryBasal.Type.SUPERBOLUS).toVisibility()
|
||||
if (abs(iob.basaliob) > 0.01) holder.binding.iob.setTextColor(rh.gc(R.color.colorActive)) else holder.binding.iob.setTextColor(holder.binding.duration.currentTextColor)
|
||||
holder.binding.remove.tag = tempBasal
|
||||
|
||||
holder.binding.cbRemove.visibility = (tempBasal.isValid && (removeActionMode != null)).toVisibility()
|
||||
holder.binding.cbRemove.setOnCheckedChangeListener { _, value ->
|
||||
if (value) {
|
||||
selectedItems.add(tempBasal)
|
||||
} else {
|
||||
selectedItems.remove(tempBasal)
|
||||
}
|
||||
removeActionMode?.title = rh.gs(R.string.count_selected, selectedItems.size)
|
||||
}
|
||||
val nextTimestamp = if (tempBasalList.size != position + 1) tempBasalList[position + 1].timestamp else 0L
|
||||
holder.binding.delimiter.visibility = dateUtil.isSameDay(tempBasal.timestamp, nextTimestamp).toVisibility()
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = tempBasalList.size
|
||||
override fun getItemCount() = tempBasalList.size
|
||||
|
||||
inner class TempBasalsViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||
|
||||
val binding = TreatmentsTempbasalsItemBinding.bind(itemView)
|
||||
|
||||
init {
|
||||
binding.remove.setOnClickListener { v: View ->
|
||||
val tempBasal = v.tag as TemporaryBasal
|
||||
var extendedBolus: ExtendedBolus? = null
|
||||
val isFakeExtended = tempBasal.type == TemporaryBasal.Type.FAKE_EXTENDED
|
||||
if (isFakeExtended) {
|
||||
val eb = repository.getExtendedBolusActiveAt(tempBasal.timestamp).blockingGet()
|
||||
extendedBolus = if (eb is ValueWrapper.Existing) eb.value else null
|
||||
}
|
||||
val profile = profileFunction.getProfile(dateUtil.now())
|
||||
?: return@setOnClickListener
|
||||
context?.let {
|
||||
OKDialog.showConfirmation(it, rh.gs(R.string.removerecord),
|
||||
"""
|
||||
${if (isFakeExtended) rh.gs(R.string.extended_bolus) else rh.gs(R.string.tempbasal_label)}: ${tempBasal.toStringFull(profile, dateUtil)}
|
||||
${rh.gs(R.string.date)}: ${dateUtil.dateAndTimeString(tempBasal.timestamp)}
|
||||
""".trimIndent(),
|
||||
{ _: DialogInterface?, _: Int ->
|
||||
if (isFakeExtended && extendedBolus != null) {
|
||||
uel.log(Action.EXTENDED_BOLUS_REMOVED, Sources.Treatments,
|
||||
ValueWithUnit.Timestamp(extendedBolus.timestamp),
|
||||
ValueWithUnit.Insulin(extendedBolus.amount),
|
||||
ValueWithUnit.UnitPerHour(extendedBolus.rate),
|
||||
ValueWithUnit.Minute(TimeUnit.MILLISECONDS.toMinutes(extendedBolus.duration).toInt()))
|
||||
disposable += repository.runTransactionForResult(InvalidateExtendedBolusTransaction(extendedBolus.id))
|
||||
.subscribe(
|
||||
{ aapsLogger.debug(LTag.DATABASE, "Removed extended bolus $extendedBolus") },
|
||||
{ aapsLogger.error(LTag.DATABASE, "Error while invalidating extended bolus", it) })
|
||||
} else if (!isFakeExtended) {
|
||||
uel.log(Action.TEMP_BASAL_REMOVED, Sources.Treatments,
|
||||
ValueWithUnit.Timestamp(tempBasal.timestamp),
|
||||
if (tempBasal.isAbsolute) ValueWithUnit.UnitPerHour(tempBasal.rate) else ValueWithUnit.Percent(tempBasal.rate.toInt()),
|
||||
ValueWithUnit.Minute(T.msecs(tempBasal.duration).mins().toInt()))
|
||||
disposable += repository.runTransactionForResult(InvalidateTemporaryBasalTransaction(tempBasal.id))
|
||||
.subscribe(
|
||||
{ aapsLogger.debug(LTag.DATABASE, "Removed temporary basal $tempBasal") },
|
||||
{ aapsLogger.error(LTag.DATABASE, "Error while invalidating temporary basal", it) })
|
||||
}
|
||||
}, null)
|
||||
}
|
||||
}
|
||||
binding.remove.paintFlags = binding.remove.paintFlags or Paint.UNDERLINE_TEXT_FLAG
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||
inflater.inflate(R.menu.menu_treatments_temp_basal, menu)
|
||||
super.onCreateOptionsMenu(menu, inflater)
|
||||
}
|
||||
|
||||
override fun onPrepareOptionsMenu(menu: Menu) {
|
||||
menu.findItem(R.id.nav_hide_invalidated)?.isVisible = showInvalidated
|
||||
menu.findItem(R.id.nav_show_invalidated)?.isVisible = !showInvalidated
|
||||
|
||||
return super.onPrepareOptionsMenu(menu)
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
return when (item.itemId) {
|
||||
R.id.nav_remove_items -> {
|
||||
removeActionMode = toolbar?.startActionMode(RemoveActionModeCallback())
|
||||
true
|
||||
}
|
||||
|
||||
R.id.nav_show_invalidated -> {
|
||||
showInvalidated = true
|
||||
rxBus.send(EventTreatmentUpdateGui())
|
||||
true
|
||||
}
|
||||
|
||||
R.id.nav_hide_invalidated -> {
|
||||
showInvalidated = false
|
||||
rxBus.send(EventTreatmentUpdateGui())
|
||||
true
|
||||
}
|
||||
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
inner class RemoveActionModeCallback : ActionMode.Callback {
|
||||
|
||||
override fun onCreateActionMode(mode: ActionMode, menu: Menu?): Boolean {
|
||||
mode.menuInflater.inflate(R.menu.menu_delete_selection, menu)
|
||||
selectedItems = mutableListOf()
|
||||
mode.title = rh.gs(R.string.count_selected, selectedItems.size)
|
||||
binding.recyclerview.adapter?.notifyDataSetChanged()
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onPrepareActionMode(mode: ActionMode?, menu: Menu?) = false
|
||||
|
||||
override fun onActionItemClicked(mode: ActionMode, item: MenuItem): Boolean {
|
||||
return when (item.itemId) {
|
||||
R.id.remove_selected -> {
|
||||
removeSelected()
|
||||
mode.finish()
|
||||
true
|
||||
}
|
||||
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroyActionMode(mode: ActionMode?) {
|
||||
removeActionMode = null
|
||||
binding.recyclerview.adapter?.notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
|
||||
private fun getConfirmationText(): String {
|
||||
if (selectedItems.size == 1) {
|
||||
val tempBasal = selectedItems.first()
|
||||
val isFakeExtended = tempBasal.type == TemporaryBasal.Type.FAKE_EXTENDED
|
||||
val profile = profileFunction.getProfile(dateUtil.now())
|
||||
if (profile != null)
|
||||
return "${if (isFakeExtended) rh.gs(R.string.extended_bolus) else rh.gs(R.string.tempbasal_label)}: ${tempBasal.toStringFull(profile, dateUtil)}\n" +
|
||||
"${rh.gs(R.string.date)}: ${dateUtil.dateAndTimeString(tempBasal.timestamp)}"
|
||||
}
|
||||
return rh.gs(R.string.confirm_remove_multiple_items, selectedItems.size)
|
||||
}
|
||||
|
||||
private fun removeSelected() {
|
||||
// TODO check if item should not be delete val profile = profileFunction.getProfile(dateUtil.now()) == null
|
||||
if (selectedItems.size > 0)
|
||||
activity?.let { activity ->
|
||||
OKDialog.showConfirmation(activity, rh.gs(R.string.removerecord), getConfirmationText(), Runnable {
|
||||
selectedItems.forEach { tempBasal ->
|
||||
var extendedBolus: ExtendedBolus? = null
|
||||
val isFakeExtended = tempBasal.type == TemporaryBasal.Type.FAKE_EXTENDED
|
||||
if (isFakeExtended) {
|
||||
val eb = repository.getExtendedBolusActiveAt(tempBasal.timestamp).blockingGet()
|
||||
extendedBolus = if (eb is ValueWrapper.Existing) eb.value else null
|
||||
}
|
||||
if (isFakeExtended && extendedBolus != null) {
|
||||
uel.log(
|
||||
Action.EXTENDED_BOLUS_REMOVED, Sources.Treatments,
|
||||
ValueWithUnit.Timestamp(extendedBolus.timestamp),
|
||||
ValueWithUnit.Insulin(extendedBolus.amount),
|
||||
ValueWithUnit.UnitPerHour(extendedBolus.rate),
|
||||
ValueWithUnit.Minute(TimeUnit.MILLISECONDS.toMinutes(extendedBolus.duration).toInt())
|
||||
)
|
||||
disposable += repository.runTransactionForResult(InvalidateExtendedBolusTransaction(extendedBolus.id))
|
||||
.subscribe(
|
||||
{ aapsLogger.debug(LTag.DATABASE, "Removed extended bolus $extendedBolus") },
|
||||
{ aapsLogger.error(LTag.DATABASE, "Error while invalidating extended bolus", it) })
|
||||
} else if (!isFakeExtended) {
|
||||
uel.log(
|
||||
Action.TEMP_BASAL_REMOVED, Sources.Treatments,
|
||||
ValueWithUnit.Timestamp(tempBasal.timestamp),
|
||||
if (tempBasal.isAbsolute) ValueWithUnit.UnitPerHour(tempBasal.rate) else ValueWithUnit.Percent(tempBasal.rate.toInt()),
|
||||
ValueWithUnit.Minute(T.msecs(tempBasal.duration).mins().toInt())
|
||||
)
|
||||
disposable += repository.runTransactionForResult(InvalidateTemporaryBasalTransaction(tempBasal.id))
|
||||
.subscribe(
|
||||
{ aapsLogger.debug(LTag.DATABASE, "Removed temporary basal $tempBasal") },
|
||||
{ aapsLogger.error(LTag.DATABASE, "Error while invalidating temporary basal", it) })
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
package info.nightscout.androidaps.activities.fragments
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.*
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import dagger.android.support.DaggerFragment
|
||||
|
@ -30,6 +28,7 @@ import info.nightscout.androidaps.utils.alertDialogs.OKDialog
|
|||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import info.nightscout.androidaps.utils.rx.AapsSchedulers
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
import io.reactivex.rxkotlin.plusAssign
|
||||
import java.util.concurrent.TimeUnit
|
||||
import javax.inject.Inject
|
||||
|
||||
|
@ -51,7 +50,7 @@ class TreatmentsUserEntryFragment : DaggerFragment() {
|
|||
|
||||
private val millsToThePastFiltered = T.days(30).msecs()
|
||||
private val millsToThePastUnFiltered = T.days(3).msecs()
|
||||
|
||||
private var showLoop = false
|
||||
private var _binding: TreatmentsUserEntryFragmentBinding? = null
|
||||
|
||||
// This property is only valid between onCreateView and
|
||||
|
@ -63,35 +62,33 @@ class TreatmentsUserEntryFragment : DaggerFragment() {
|
|||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
setHasOptionsMenu(true)
|
||||
binding.recyclerview.setHasFixedSize(true)
|
||||
binding.recyclerview.layoutManager = LinearLayoutManager(view.context)
|
||||
binding.ueExportToXml.setOnClickListener {
|
||||
activity?.let { activity ->
|
||||
OKDialog.showConfirmation(activity, rh.gs(R.string.ue_export_to_csv) + "?") {
|
||||
uel.log(Action.EXPORT_CSV, Sources.Treatments)
|
||||
importExportPrefs.exportUserEntriesCsv(activity)
|
||||
}
|
||||
}
|
||||
|
||||
fun exportUserEnteries() {
|
||||
activity?.let { activity ->
|
||||
OKDialog.showConfirmation(activity, rh.gs(R.string.ue_export_to_csv) + "?") {
|
||||
uel.log(Action.EXPORT_CSV, Sources.Treatments)
|
||||
importExportPrefs.exportUserEntriesCsv(activity)
|
||||
}
|
||||
}
|
||||
binding.showLoop.setOnCheckedChangeListener { _, _ ->
|
||||
rxBus.send(EventTreatmentUpdateGui())
|
||||
}
|
||||
}
|
||||
|
||||
fun swapAdapter() {
|
||||
val now = System.currentTimeMillis()
|
||||
if (binding.showLoop.isChecked)
|
||||
disposable.add( repository
|
||||
.getUserEntryDataFromTime(now - millsToThePastUnFiltered)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe { list -> binding.recyclerview.swapAdapter(UserEntryAdapter(list), true) }
|
||||
)
|
||||
else
|
||||
disposable.add( repository
|
||||
.getUserEntryFilteredDataFromTime(now - millsToThePastFiltered)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe { list -> binding.recyclerview.swapAdapter(UserEntryAdapter(list), true) }
|
||||
)
|
||||
disposable +=
|
||||
if (showLoop)
|
||||
repository
|
||||
.getUserEntryDataFromTime(now - millsToThePastUnFiltered)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe { list -> binding.recyclerview.swapAdapter(UserEntryAdapter(list), true) }
|
||||
else
|
||||
repository
|
||||
.getUserEntryFilteredDataFromTime(now - millsToThePastFiltered)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe { list -> binding.recyclerview.swapAdapter(UserEntryAdapter(list), true) }
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
|
@ -99,15 +96,15 @@ class TreatmentsUserEntryFragment : DaggerFragment() {
|
|||
super.onResume()
|
||||
swapAdapter()
|
||||
|
||||
disposable.add(rxBus
|
||||
disposable += rxBus
|
||||
.toObservable(EventPreferenceChange::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
.subscribe({ swapAdapter() }, fabricPrivacy::logException))
|
||||
disposable.add(rxBus
|
||||
.subscribe({ swapAdapter() }, fabricPrivacy::logException)
|
||||
disposable += rxBus
|
||||
.toObservable(EventTreatmentUpdateGui::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
.debounce(1L, TimeUnit.SECONDS)
|
||||
.subscribe({ swapAdapter() }, fabricPrivacy::logException))
|
||||
.subscribe({ swapAdapter() }, fabricPrivacy::logException)
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
|
@ -132,7 +129,7 @@ class TreatmentsUserEntryFragment : DaggerFragment() {
|
|||
|
||||
override fun onBindViewHolder(holder: UserEntryViewHolder, position: Int) {
|
||||
val current = entries[position]
|
||||
val sameDayPrevious = position > 0 && dateUtil.isSameDay(current.timestamp, entries[position-1].timestamp)
|
||||
val sameDayPrevious = position > 0 && dateUtil.isSameDay(current.timestamp, entries[position - 1].timestamp)
|
||||
holder.binding.date.visibility = sameDayPrevious.not().toVisibility()
|
||||
holder.binding.date.text = dateUtil.dateString(current.timestamp)
|
||||
holder.binding.time.text = dateUtil.timeStringWithSeconds(current.timestamp)
|
||||
|
@ -152,7 +149,41 @@ class TreatmentsUserEntryFragment : DaggerFragment() {
|
|||
val binding = TreatmentsUserEntryItemBinding.bind(itemView)
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = entries.size
|
||||
override fun getItemCount() = entries.size
|
||||
}
|
||||
|
||||
}
|
||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||
inflater.inflate(R.menu.menu_treatments_user_entry, menu)
|
||||
super.onCreateOptionsMenu(menu, inflater)
|
||||
}
|
||||
|
||||
override fun onPrepareOptionsMenu(menu: Menu) {
|
||||
menu.findItem(R.id.nav_hide_loop)?.isVisible = showLoop
|
||||
menu.findItem(R.id.nav_show_loop)?.isVisible = !showLoop
|
||||
|
||||
return super.onPrepareOptionsMenu(menu)
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
return when (item.itemId) {
|
||||
R.id.nav_show_loop -> {
|
||||
showLoop = true
|
||||
rxBus.send(EventTreatmentUpdateGui())
|
||||
true
|
||||
}
|
||||
|
||||
R.id.nav_hide_loop -> {
|
||||
showLoop = false
|
||||
rxBus.send(EventTreatmentUpdateGui())
|
||||
true
|
||||
}
|
||||
|
||||
R.id.nav_export -> {
|
||||
exportUserEnteries()
|
||||
true
|
||||
}
|
||||
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,54 +1,10 @@
|
|||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
tools:context="info.nightscout.androidaps.activities.fragments.TreatmentsBolusCarbsFragment">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<info.nightscout.androidaps.utils.ui.SingleClickButton
|
||||
android:id="@+id/refresh_from_nightscout"
|
||||
style="?android:attr/buttonStyle"
|
||||
android:layout_width="0px"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_weight="1"
|
||||
android:drawableStart="@drawable/ic_refresh"
|
||||
android:text="@string/nav_refreshtreatments" />
|
||||
|
||||
<info.nightscout.androidaps.utils.ui.SingleClickButton
|
||||
android:id="@+id/delete_future_treatments"
|
||||
style="?android:attr/buttonStyle"
|
||||
android:layout_width="0px"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_weight="1"
|
||||
android:drawableStart="@drawable/ic_remove"
|
||||
android:text="@string/deletefuturetreatments" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/show_invalidated"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end|center_vertical"
|
||||
android:checked="false"
|
||||
android:paddingEnd="5dp"
|
||||
tools:ignore="RtlSymmetry" />
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:contentDescription="@string/show_removed"
|
||||
app:srcCompat="@drawable/ic_visibility" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recyclerview"
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
@ -161,14 +161,12 @@
|
|||
android:text="@string/invalid"
|
||||
android:textColor="@android:color/holo_red_light" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/bolus_remove"
|
||||
<CheckBox
|
||||
android:id="@+id/cb_bolus_remove"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="5dp"
|
||||
android:text="@string/remove_button"
|
||||
android:textAlignment="viewEnd"
|
||||
android:textColor="@android:color/holo_orange_light" />
|
||||
android:contentDescription="@string/select_for_removal"
|
||||
android:visibility="gone" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
|
@ -257,13 +255,21 @@
|
|||
|
||||
<TextView
|
||||
android:id="@+id/carbs_remove"
|
||||
android:visibility="gone"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="5dp"
|
||||
|
||||
android:text="@string/remove_button"
|
||||
android:textAlignment="viewEnd"
|
||||
android:textColor="@android:color/holo_orange_light" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/cb_carbs_remove"
|
||||
android:visibility="gone"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
|
|
|
@ -1,54 +1,10 @@
|
|||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
tools:context="info.nightscout.androidaps.activities.fragments.TreatmentsCareportalFragment">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<info.nightscout.androidaps.utils.ui.SingleClickButton
|
||||
android:id="@+id/refresh_from_nightscout"
|
||||
style="?android:attr/buttonStyle"
|
||||
android:layout_width="0px"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_weight="1"
|
||||
android:drawableStart="@drawable/ic_refresh"
|
||||
android:text="@string/nav_refreshtreatments" />
|
||||
|
||||
<info.nightscout.androidaps.utils.ui.SingleClickButton
|
||||
android:id="@+id/remove_androidaps_started_events"
|
||||
style="?android:attr/buttonStyle"
|
||||
android:layout_width="0px"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_weight="1"
|
||||
android:drawableStart="@drawable/ic_remove"
|
||||
android:text="@string/careportal_removestartedevents" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/show_invalidated"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end|center_vertical"
|
||||
android:checked="false"
|
||||
android:paddingEnd="5dp"
|
||||
tools:ignore="RtlSymmetry" />
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:contentDescription="@string/show_removed"
|
||||
app:srcCompat="@drawable/ic_visibility" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recyclerview"
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
@ -112,14 +112,12 @@
|
|||
android:text="Activity"
|
||||
tools:ignore="HardcodedText,RtlSymmetry" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/remove"
|
||||
<CheckBox
|
||||
android:id="@+id/cb_remove"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="10dp"
|
||||
android:text="@string/remove_button"
|
||||
android:textAlignment="viewEnd"
|
||||
android:textColor="@android:color/holo_orange_light" />
|
||||
android:contentDescription="@string/select_for_removal"
|
||||
android:visibility="gone" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
|
|
@ -1,34 +1,10 @@
|
|||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
tools:context="info.nightscout.androidaps.activities.fragments.TreatmentsExtendedBolusesFragment">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/show_invalidated"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end|center_vertical"
|
||||
android:checked="false"
|
||||
android:paddingEnd="5dp"
|
||||
tools:ignore="RtlSymmetry" />
|
||||
|
||||
<ImageView
|
||||
app:srcCompat="@drawable/ic_visibility"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:contentDescription="@string/show_removed" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recyclerview"
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
@ -153,14 +153,12 @@
|
|||
android:text="@string/invalid"
|
||||
android:textColor="@android:color/holo_red_light" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/remove"
|
||||
<CheckBox
|
||||
android:id="@+id/cb_remove"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="5dp"
|
||||
android:text="@string/remove_button"
|
||||
android:textAlignment="viewEnd"
|
||||
android:textColor="@android:color/holo_orange_light" />
|
||||
android:contentDescription="@string/select_for_removal"
|
||||
android:visibility="gone" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
|
|
|
@ -6,6 +6,13 @@
|
|||
android:orientation="vertical"
|
||||
tools:context="info.nightscout.androidaps.activities.TreatmentsActivity">
|
||||
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/colorPrimary"
|
||||
android:minHeight="?attr/actionBarSize"
|
||||
app:titleTextColor="@android:color/white" />
|
||||
|
||||
<com.google.android.flexbox.FlexboxLayout
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
@ -1,44 +1,10 @@
|
|||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
tools:context="info.nightscout.androidaps.activities.fragments.TreatmentsProfileSwitchFragment">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<info.nightscout.androidaps.utils.ui.SingleClickButton
|
||||
android:id="@+id/refresh_from_nightscout"
|
||||
style="?android:attr/buttonStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_weight="1"
|
||||
android:drawableStart="@drawable/ic_refresh"
|
||||
android:text="@string/refresheventsfromnightscout" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/show_invalidated"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end|center_vertical"
|
||||
android:checked="false"
|
||||
android:paddingEnd="5dp"
|
||||
tools:ignore="RtlSymmetry" />
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:contentDescription="@string/show_removed"
|
||||
app:srcCompat="@drawable/ic_visibility" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recyclerview"
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
@ -124,15 +124,12 @@
|
|||
android:textAlignment="viewEnd"
|
||||
android:textColor="@android:color/holo_blue_light" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/remove"
|
||||
<CheckBox
|
||||
android:id="@+id/cb_remove"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingStart="10dp"
|
||||
android:paddingEnd="5dp"
|
||||
android:text="@string/remove_button"
|
||||
android:textAlignment="viewEnd"
|
||||
android:textColor="@android:color/holo_orange_light" />
|
||||
android:contentDescription="@string/select_for_removal"
|
||||
android:visibility="gone" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
|
|
@ -1,36 +1,10 @@
|
|||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
tools:context="info.nightscout.androidaps.activities.fragments.TreatmentsTemporaryBasalsFragment">
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/show_invalidated"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end|center_vertical"
|
||||
android:checked="false"
|
||||
android:paddingEnd="5dp"
|
||||
tools:ignore="RtlSymmetry" />
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:contentDescription="@string/show_removed"
|
||||
app:srcCompat="@drawable/ic_visibility" />
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recyclerview"
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
@ -172,15 +172,12 @@
|
|||
android:text="@string/invalid"
|
||||
android:textColor="@android:color/holo_red_light" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/remove"
|
||||
<CheckBox
|
||||
android:id="@+id/cb_remove"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="5dp"
|
||||
android:visibility="gone"
|
||||
android:text="@string/remove_button"
|
||||
android:textAlignment="viewEnd"
|
||||
android:textColor="@android:color/holo_orange_light" />
|
||||
android:contentDescription="@string/select_for_removal"
|
||||
android:visibility="gone" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
|
|
|
@ -1,45 +1,10 @@
|
|||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
tools:context="info.nightscout.androidaps.activities.fragments.TreatmentsTempTargetFragment">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<info.nightscout.androidaps.utils.ui.SingleClickButton
|
||||
android:id="@+id/refresh_from_nightscout"
|
||||
style="?android:attr/buttonStyle"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_weight="1"
|
||||
android:drawableStart="@drawable/ic_refresh"
|
||||
android:text="@string/refresheventsfromnightscout"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/show_invalidated"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end|center_vertical"
|
||||
android:checked="false"
|
||||
android:paddingEnd="5dp"
|
||||
tools:ignore="RtlSymmetry" />
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:contentDescription="@string/show_removed"
|
||||
app:srcCompat="@drawable/ic_visibility" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recyclerview"
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
@ -147,14 +147,12 @@
|
|||
android:text="@string/invalid"
|
||||
android:textColor="@android:color/holo_red_light" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/remove"
|
||||
<CheckBox
|
||||
android:id="@+id/cb_remove"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="10dp"
|
||||
android:text="@string/remove_button"
|
||||
android:textAlignment="viewEnd"
|
||||
android:textColor="@android:color/holo_orange_light" />
|
||||
android:contentDescription="@string/select_for_removal"
|
||||
android:visibility="gone" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
|
|
@ -6,40 +6,6 @@
|
|||
android:orientation="vertical"
|
||||
tools:context="info.nightscout.androidaps.activities.fragments.TreatmentsUserEntryFragment">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<info.nightscout.androidaps.utils.ui.SingleClickButton
|
||||
android:id="@+id/ue_export_to_xml"
|
||||
style="?android:attr/buttonStyle"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_weight="1"
|
||||
android:drawableStart="@drawable/ic_header_export"
|
||||
android:text="@string/ue_export_to_csv" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/show_loop"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end|center_vertical"
|
||||
android:checked="false"
|
||||
android:paddingEnd="5dp"
|
||||
tools:ignore="RtlSymmetry" />
|
||||
|
||||
<ImageView
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:contentDescription="@string/show_calculation"
|
||||
app:srcCompat="@drawable/ic_loop_closed_white" />
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recyclerview"
|
||||
android:layout_width="match_parent"
|
||||
|
|
11
app/src/main/res/menu/menu_delete_selection.xml
Normal file
11
app/src/main/res/menu/menu_delete_selection.xml
Normal file
|
@ -0,0 +1,11 @@
|
|||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<item
|
||||
android:id="@+id/remove_selected"
|
||||
android:icon="@drawable/ic_trash"
|
||||
android:iconTint="@color/white"
|
||||
android:title="@string/remove_selected_items"
|
||||
app:showAsAction="always" />
|
||||
|
||||
</menu>
|
25
app/src/main/res/menu/menu_treatments_carbs_bolus.xml
Normal file
25
app/src/main/res/menu/menu_treatments_carbs_bolus.xml
Normal file
|
@ -0,0 +1,25 @@
|
|||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<item
|
||||
android:id="@+id/nav_remove_items"
|
||||
android:title="@string/remove_items"
|
||||
app:showAsAction="never" />
|
||||
<item
|
||||
android:id="@+id/nav_show_invalidated"
|
||||
android:title="@string/show_invalidated"
|
||||
app:showAsAction="never" />
|
||||
<item
|
||||
android:id="@+id/nav_hide_invalidated"
|
||||
android:title="@string/hide_invalidated"
|
||||
app:showAsAction="never" />
|
||||
<item
|
||||
android:id="@+id/nav_delete_future"
|
||||
android:title="@string/delete_future_treatments"
|
||||
app:showAsAction="never" />
|
||||
<item
|
||||
android:id="@+id/nav_refresh_ns"
|
||||
android:title="@string/refresh_from_nightscout"
|
||||
app:showAsAction="never" />
|
||||
|
||||
</menu>
|
25
app/src/main/res/menu/menu_treatments_careportal.xml
Normal file
25
app/src/main/res/menu/menu_treatments_careportal.xml
Normal file
|
@ -0,0 +1,25 @@
|
|||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<item
|
||||
android:id="@+id/nav_remove_items"
|
||||
android:title="@string/remove_items"
|
||||
app:showAsAction="never" />
|
||||
<item
|
||||
android:id="@+id/nav_show_invalidated"
|
||||
android:title="@string/show_invalidated"
|
||||
app:showAsAction="never" />
|
||||
<item
|
||||
android:id="@+id/nav_hide_invalidated"
|
||||
android:title="@string/hide_invalidated"
|
||||
app:showAsAction="never" />
|
||||
<item
|
||||
android:id="@+id/nav_refresh_ns"
|
||||
android:title="@string/refresh_from_nightscout"
|
||||
app:showAsAction="never" />
|
||||
<item
|
||||
android:id="@+id/nav_remove_started_events"
|
||||
android:title="@string/careportal_removestartedevents"
|
||||
app:showAsAction="never" />
|
||||
|
||||
</menu>
|
17
app/src/main/res/menu/menu_treatments_extended_bolus.xml
Normal file
17
app/src/main/res/menu/menu_treatments_extended_bolus.xml
Normal file
|
@ -0,0 +1,17 @@
|
|||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<item
|
||||
android:id="@+id/nav_remove_items"
|
||||
android:title="@string/remove_items"
|
||||
app:showAsAction="never" />
|
||||
<item
|
||||
android:id="@+id/nav_show_invalidated"
|
||||
android:title="@string/show_invalidated"
|
||||
app:showAsAction="never" />
|
||||
<item
|
||||
android:id="@+id/nav_hide_invalidated"
|
||||
android:title="@string/hide_invalidated"
|
||||
app:showAsAction="never" />
|
||||
|
||||
</menu>
|
17
app/src/main/res/menu/menu_treatments_profile_switch.xml
Normal file
17
app/src/main/res/menu/menu_treatments_profile_switch.xml
Normal file
|
@ -0,0 +1,17 @@
|
|||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<item
|
||||
android:id="@+id/nav_remove_items"
|
||||
android:title="@string/remove_items"
|
||||
app:showAsAction="never" />
|
||||
<item
|
||||
android:id="@+id/nav_show_invalidated"
|
||||
android:title="@string/show_invalidated"
|
||||
app:showAsAction="never" />
|
||||
<item
|
||||
android:id="@+id/nav_hide_invalidated"
|
||||
android:title="@string/hide_invalidated"
|
||||
app:showAsAction="never" />
|
||||
|
||||
</menu>
|
17
app/src/main/res/menu/menu_treatments_temp_basal.xml
Normal file
17
app/src/main/res/menu/menu_treatments_temp_basal.xml
Normal file
|
@ -0,0 +1,17 @@
|
|||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<item
|
||||
android:id="@+id/nav_remove_items"
|
||||
android:title="@string/remove_items"
|
||||
app:showAsAction="never" />
|
||||
<item
|
||||
android:id="@+id/nav_show_invalidated"
|
||||
android:title="@string/show_invalidated"
|
||||
app:showAsAction="never" />
|
||||
<item
|
||||
android:id="@+id/nav_hide_invalidated"
|
||||
android:title="@string/hide_invalidated"
|
||||
app:showAsAction="never" />
|
||||
|
||||
</menu>
|
21
app/src/main/res/menu/menu_treatments_temp_target.xml
Normal file
21
app/src/main/res/menu/menu_treatments_temp_target.xml
Normal file
|
@ -0,0 +1,21 @@
|
|||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<item
|
||||
android:id="@+id/nav_remove_items"
|
||||
android:title="@string/remove_items"
|
||||
app:showAsAction="never" />
|
||||
<item
|
||||
android:id="@+id/nav_show_invalidated"
|
||||
android:title="@string/show_invalidated"
|
||||
app:showAsAction="never" />
|
||||
<item
|
||||
android:id="@+id/nav_hide_invalidated"
|
||||
android:title="@string/hide_invalidated"
|
||||
app:showAsAction="never" />
|
||||
<item
|
||||
android:id="@+id/nav_refresh_ns"
|
||||
android:title="@string/refresh_from_nightscout"
|
||||
app:showAsAction="never" />
|
||||
|
||||
</menu>
|
17
app/src/main/res/menu/menu_treatments_user_entry.xml
Normal file
17
app/src/main/res/menu/menu_treatments_user_entry.xml
Normal file
|
@ -0,0 +1,17 @@
|
|||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<item
|
||||
android:id="@+id/nav_show_loop"
|
||||
android:title="@string/show_loop"
|
||||
app:showAsAction="never" />
|
||||
<item
|
||||
android:id="@+id/nav_hide_loop"
|
||||
android:title="@string/hide_loop"
|
||||
app:showAsAction="never" />
|
||||
<item
|
||||
android:id="@+id/nav_export"
|
||||
android:title="@string/ue_export_to_csv"
|
||||
app:showAsAction="never" />
|
||||
|
||||
</menu>
|
|
@ -826,6 +826,9 @@
|
|||
<string name="sensitivity_raises_target_summary">When sensitivity is detected, raise the target glucose</string>
|
||||
<string name="key_keep_screen_on" translatable="false">keep_screen_on</string>
|
||||
<string name="careportal_removestartedevents">Clean AndroidAPS started</string>
|
||||
<string name="show_invalidated">Show invalidated</string>
|
||||
<string name="hide_invalidated">Hide invalidated</string>
|
||||
<string name="remove_items">Remove items</string>
|
||||
<string name="storedsettingsfound">Stored settings found</string>
|
||||
<string name="allow_hardware_pump_text">Attention: If you activate and connect to a hardware pump, AndroidAPS will copy the basal settings from the profile to the pump, overwriting the existing basal rate stored on the pump. Make sure you have the correct basal setting in AndroidAPS. If you are not sure or don\'t want to overwrite the basal settings on your pump, press cancel and repeat switching to the pump at a later time.</string>
|
||||
<string name="error_adding_treatment_title">Treatment data incomplete</string>
|
||||
|
@ -1207,4 +1210,14 @@
|
|||
<string name="wear_unknown_action_string">Unknown action command:</string>
|
||||
<string name="overview_editquickwizard_percentage">Percentage</string>
|
||||
<string name="app_default">Application default</string>
|
||||
<string name="refresh_from_nightscout">Refresh from Nightscout</string>
|
||||
<string name="remove_selected_items">Remove selected items</string>
|
||||
<string name="select_for_removal">Select for removal</string>
|
||||
<string name="profile_changes">Profile changes</string>
|
||||
<string name="tempt_targets">Temp Targets</string>
|
||||
<string name="carbs_and_bolus">Carbs and bolus</string>
|
||||
<string name="confirm_remove_multiple_items">Are you sure you want to remove %1$d items</string>
|
||||
<string name="hide_loop">Hide loop</string>
|
||||
<string name="show_loop">Show loop</string>
|
||||
<string name="count_selected">%1$d selected</string>
|
||||
</resources>
|
||||
|
|
5
core/src/main/res/drawable/ic_close.xml
Normal file
5
core/src/main/res/drawable/ic_close.xml
Normal file
|
@ -0,0 +1,5 @@
|
|||
<vector android:height="24dp" android:tint="#FFFFFF"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="@android:color/white" android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z"/>
|
||||
</vector>
|
|
@ -3,6 +3,8 @@
|
|||
<item name="colorPrimary">@color/colorPrimary</item>
|
||||
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
||||
<item name="colorAccent">@color/colorAccent</item>
|
||||
<item name="windowActionModeOverlay">true</item>
|
||||
<item name="actionModeCloseDrawable">@drawable/ic_close</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
|
@ -469,6 +469,7 @@
|
|||
<string name="uel_stat_reset">STAT RESET</string>
|
||||
<string name="uel_delete_logs">DELETE LOGS</string>
|
||||
<string name="uel_delete_future_treatments">DELETE FUTURE TREATMENTS</string>
|
||||
<string name="delete_future_treatments">Delete future treatments</string>
|
||||
<string name="uel_export_settings">EXPORT SETTINGS</string>
|
||||
<string name="uel_import_settings">IMPORT SETTINGS</string>
|
||||
<string name="uel_reset_databases">RESET DATABASES</string>
|
||||
|
|
Loading…
Reference in a new issue