ProfilePlugin -> plugins module

This commit is contained in:
Milos Kozak 2022-11-04 19:13:37 +01:00
parent 683f87cd15
commit efcae9f073
60 changed files with 432 additions and 374 deletions

View file

@ -18,8 +18,8 @@ import info.nightscout.androidaps.dialogs.ProfileViewerDialog
import info.nightscout.androidaps.extensions.toVisibility import info.nightscout.androidaps.extensions.toVisibility
import info.nightscout.androidaps.interfaces.ActivePlugin import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.interfaces.ProfileFunction import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.plugins.profile.local.LocalProfilePlugin import info.nightscout.plugins.profile.ProfilePlugin
import info.nightscout.androidaps.plugins.profile.local.events.EventLocalProfileChanged import info.nightscout.plugins.profile.events.EventLocalProfileChanged
import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.T import info.nightscout.androidaps.utils.T
@ -41,7 +41,7 @@ class ProfileHelperActivity : NoSplashAppCompatActivity() {
@Inject lateinit var profileFunction: ProfileFunction @Inject lateinit var profileFunction: ProfileFunction
@Inject lateinit var defaultProfile: DefaultProfile @Inject lateinit var defaultProfile: DefaultProfile
@Inject lateinit var defaultProfileDPV: DefaultProfileDPV @Inject lateinit var defaultProfileDPV: DefaultProfileDPV
@Inject lateinit var localProfilePlugin: LocalProfilePlugin @Inject lateinit var profilePlugin: ProfilePlugin
@Inject lateinit var dateUtil: DateUtil @Inject lateinit var dateUtil: DateUtil
@Inject lateinit var activePlugin: ActivePlugin @Inject lateinit var activePlugin: ActivePlugin
@Inject lateinit var repository: AppRepository @Inject lateinit var repository: AppRepository
@ -135,8 +135,8 @@ class ProfileHelperActivity : NoSplashAppCompatActivity() {
else defaultProfileDPV.profile(age, tdd, pct / 100.0, profileFunction.getUnits()) else defaultProfileDPV.profile(age, tdd, pct / 100.0, profileFunction.getUnits())
profile?.let { profile?.let {
OKDialog.showConfirmation(this, rh.gs(R.string.careportal_profileswitch), rh.gs(R.string.copytolocalprofile), Runnable { OKDialog.showConfirmation(this, rh.gs(R.string.careportal_profileswitch), rh.gs(R.string.copytolocalprofile), Runnable {
localProfilePlugin.addProfile( profilePlugin.addProfile(
localProfilePlugin.copyFrom( profilePlugin.copyFrom(
it, "DefaultProfile " + it, "DefaultProfile " +
dateUtil.dateAndTimeAndSecondsString(dateUtil.now()) dateUtil.dateAndTimeAndSecondsString(dateUtil.now())
.replace(".", "/") .replace(".", "/")

View file

@ -30,8 +30,8 @@ import info.nightscout.androidaps.logging.UserEntryLogger
import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.plugins.general.nsclient.events.EventNSClientRestart import info.nightscout.plugins.general.nsclient.events.EventNSClientRestart
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventNewHistoryData import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventNewHistoryData
import info.nightscout.androidaps.plugins.profile.local.LocalProfilePlugin import info.nightscout.plugins.profile.ProfilePlugin
import info.nightscout.androidaps.plugins.profile.local.events.EventLocalProfileChanged import info.nightscout.plugins.profile.events.EventLocalProfileChanged
import info.nightscout.androidaps.utils.ActionModeHelper import info.nightscout.androidaps.utils.ActionModeHelper
import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.FabricPrivacy
@ -55,7 +55,7 @@ class TreatmentsProfileSwitchFragment : DaggerFragment(), MenuProvider {
@Inject lateinit var rxBus: RxBus @Inject lateinit var rxBus: RxBus
@Inject lateinit var sp: SP @Inject lateinit var sp: SP
@Inject lateinit var aapsLogger: AAPSLogger @Inject lateinit var aapsLogger: AAPSLogger
@Inject lateinit var localProfilePlugin: LocalProfilePlugin @Inject lateinit var profilePlugin: ProfilePlugin
@Inject lateinit var rh: ResourceHelper @Inject lateinit var rh: ResourceHelper
@Inject lateinit var fabricPrivacy: FabricPrivacy @Inject lateinit var fabricPrivacy: FabricPrivacy
@Inject lateinit var dateUtil: DateUtil @Inject lateinit var dateUtil: DateUtil
@ -241,8 +241,8 @@ class TreatmentsProfileSwitchFragment : DaggerFragment(), MenuProvider {
ValueWithUnit.SimpleString(profileSwitch.profileName) ValueWithUnit.SimpleString(profileSwitch.profileName)
) )
val nonCustomized = profileSealed.convertToNonCustomizedProfile(dateUtil) val nonCustomized = profileSealed.convertToNonCustomizedProfile(dateUtil)
localProfilePlugin.addProfile( profilePlugin.addProfile(
localProfilePlugin.copyFrom( profilePlugin.copyFrom(
nonCustomized, nonCustomized,
profileSwitch.getCustomizedName() + " " + dateUtil.dateAndTimeString(profileSwitch.timestamp).replace(".", "_") profileSwitch.getCustomizedName() + " " + dateUtil.dateAndTimeString(profileSwitch.timestamp).replace(".", "_")
) )

View file

@ -34,7 +34,7 @@ import info.nightscout.androidaps.plugins.general.overview.OverviewFragment
import info.nightscout.androidaps.plugins.general.overview.dialogs.EditQuickWizardDialog import info.nightscout.androidaps.plugins.general.overview.dialogs.EditQuickWizardDialog
import info.nightscout.androidaps.plugins.general.tidepool.TidepoolFragment import info.nightscout.androidaps.plugins.general.tidepool.TidepoolFragment
import info.nightscout.androidaps.plugins.general.wear.WearFragment import info.nightscout.androidaps.plugins.general.wear.WearFragment
import info.nightscout.androidaps.plugins.profile.local.LocalProfileFragment import info.nightscout.plugins.profile.ProfileFragment
import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpFragment import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpFragment
import info.nightscout.androidaps.plugins.source.BGSourceFragment import info.nightscout.androidaps.plugins.source.BGSourceFragment
import info.nightscout.androidaps.utils.protection.PasswordCheck import info.nightscout.androidaps.utils.protection.PasswordCheck
@ -51,7 +51,7 @@ abstract class FragmentsModule {
@ContributesAndroidInjector abstract fun contributesConfigBuilderFragment(): ConfigBuilderFragment @ContributesAndroidInjector abstract fun contributesConfigBuilderFragment(): ConfigBuilderFragment
@ContributesAndroidInjector abstract fun contributesLocalProfileFragment(): LocalProfileFragment @ContributesAndroidInjector abstract fun contributesLocalProfileFragment(): ProfileFragment
@ContributesAndroidInjector abstract fun contributesObjectivesFragment(): ObjectivesFragment @ContributesAndroidInjector abstract fun contributesObjectivesFragment(): ObjectivesFragment
@ContributesAndroidInjector abstract fun contributesOpenAPSFragment(): OpenAPSFragment @ContributesAndroidInjector abstract fun contributesOpenAPSFragment(): OpenAPSFragment
@ContributesAndroidInjector abstract fun contributesOverviewFragment(): OverviewFragment @ContributesAndroidInjector abstract fun contributesOverviewFragment(): OverviewFragment

View file

@ -35,7 +35,7 @@ import info.nightscout.plugins.general.themes.ThemeSwitcherPlugin
import info.nightscout.androidaps.plugins.general.tidepool.TidepoolPlugin import info.nightscout.androidaps.plugins.general.tidepool.TidepoolPlugin
import info.nightscout.androidaps.plugins.general.wear.WearPlugin import info.nightscout.androidaps.plugins.general.wear.WearPlugin
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
import info.nightscout.androidaps.plugins.profile.local.LocalProfilePlugin import info.nightscout.plugins.profile.ProfilePlugin
import info.nightscout.androidaps.plugins.pump.combo.ComboPlugin import info.nightscout.androidaps.plugins.pump.combo.ComboPlugin
import info.nightscout.androidaps.plugins.pump.eopatch.EopatchPumpPlugin import info.nightscout.androidaps.plugins.pump.eopatch.EopatchPumpPlugin
import info.nightscout.androidaps.plugins.pump.insight.LocalInsightPlugin import info.nightscout.androidaps.plugins.pump.insight.LocalInsightPlugin
@ -236,7 +236,7 @@ abstract class PluginsListModule {
@AllConfigs @AllConfigs
@IntoMap @IntoMap
@IntKey(240) @IntKey(240)
abstract fun bindLocalProfilePlugin(plugin: LocalProfilePlugin): PluginBase abstract fun bindLocalProfilePlugin(plugin: ProfilePlugin): PluginBase
@Binds @Binds
@AllConfigs @AllConfigs

View file

@ -7,7 +7,7 @@ import info.nightscout.androidaps.plugins.general.nsclient.NSClientAddAckWorker
import info.nightscout.androidaps.plugins.general.nsclient.NSClientAddUpdateWorker import info.nightscout.androidaps.plugins.general.nsclient.NSClientAddUpdateWorker
import info.nightscout.androidaps.plugins.general.nsclient.NSClientMbgWorker import info.nightscout.androidaps.plugins.general.nsclient.NSClientMbgWorker
import info.nightscout.androidaps.plugins.general.nsclient.NSClientUpdateRemoveAckWorker import info.nightscout.androidaps.plugins.general.nsclient.NSClientUpdateRemoveAckWorker
import info.nightscout.androidaps.plugins.profile.local.LocalProfilePlugin import info.nightscout.plugins.profile.ProfilePlugin
import info.nightscout.androidaps.plugins.source.AidexPlugin import info.nightscout.androidaps.plugins.source.AidexPlugin
import info.nightscout.androidaps.plugins.source.DexcomPlugin import info.nightscout.androidaps.plugins.source.DexcomPlugin
import info.nightscout.androidaps.plugins.source.EversensePlugin import info.nightscout.androidaps.plugins.source.EversensePlugin
@ -30,7 +30,7 @@ abstract class WorkersModule {
@ContributesAndroidInjector abstract fun contributesTomatoWorker(): TomatoPlugin.TomatoWorker @ContributesAndroidInjector abstract fun contributesTomatoWorker(): TomatoPlugin.TomatoWorker
@ContributesAndroidInjector abstract fun contributesEversenseWorker(): EversensePlugin.EversenseWorker @ContributesAndroidInjector abstract fun contributesEversenseWorker(): EversensePlugin.EversenseWorker
@ContributesAndroidInjector abstract fun contributesNSClientSourceWorker(): NSClientSourcePlugin.NSClientSourceWorker @ContributesAndroidInjector abstract fun contributesNSClientSourceWorker(): NSClientSourcePlugin.NSClientSourceWorker
@ContributesAndroidInjector abstract fun contributesNSProfileWorker(): LocalProfilePlugin.NSProfileWorker @ContributesAndroidInjector abstract fun contributesNSProfileWorker(): ProfilePlugin.NSProfileWorker
@ContributesAndroidInjector abstract fun contributesNSClientWorker(): NSClientAddUpdateWorker @ContributesAndroidInjector abstract fun contributesNSClientWorker(): NSClientAddUpdateWorker
@ContributesAndroidInjector abstract fun contributesNSClientAddAckWorker(): NSClientAddAckWorker @ContributesAndroidInjector abstract fun contributesNSClientAddAckWorker(): NSClientAddAckWorker
@ContributesAndroidInjector abstract fun contributesNSClientUpdateRemoveAckWorker(): NSClientUpdateRemoveAckWorker @ContributesAndroidInjector abstract fun contributesNSClientUpdateRemoveAckWorker(): NSClientUpdateRemoveAckWorker

View file

@ -1,3 +1,2 @@
package info.nightscout.androidaps.events package info.nightscout.androidaps.events
class EventProfileStoreChanged : Event()

View file

@ -6,6 +6,8 @@ import android.os.Bundle
import androidx.annotation.RawRes import androidx.annotation.RawRes
import androidx.fragment.app.FragmentManager import androidx.fragment.app.FragmentManager
import info.nightscout.androidaps.MainActivity import info.nightscout.androidaps.MainActivity
import info.nightscout.androidaps.activities.SingleFragmentActivity
import info.nightscout.androidaps.dialogs.ProfileSwitchDialog
import info.nightscout.androidaps.dialogs.WizardDialog import info.nightscout.androidaps.dialogs.WizardDialog
import info.nightscout.androidaps.interfaces.ActivityNames import info.nightscout.androidaps.interfaces.ActivityNames
import info.nightscout.androidaps.services.AlarmSoundService import info.nightscout.androidaps.services.AlarmSoundService
@ -16,17 +18,12 @@ import javax.inject.Inject
class ActivityNamesImpl @Inject constructor() : ActivityNames { class ActivityNamesImpl @Inject constructor() : ActivityNames {
override val mainActivityClass: Class<*> override val mainActivityClass: Class<*> = MainActivity::class.java
get() = MainActivity::class.java override val tddStatsActivity: Class<*> = TDDStatsActivity::class.java
override val errorHelperActivity: Class<*> = ErrorHelperActivity::class.java
override val bolusProgressHelperActivity: Class<*> = BolusProgressHelperActivity::class.java
override val singleFragmentActivity: Class<*> = SingleFragmentActivity::class.java
override val tddStatsActivity: Class<*>
get() = TDDStatsActivity::class.java
override val errorHelperActivity: Class<*>
get() = ErrorHelperActivity::class.java
override val bolusProgressHelperActivity: Class<*>
get() = BolusProgressHelperActivity::class.java
override fun runAlarm(ctx: Context, status: String, title: String, @RawRes soundId: Int) { override fun runAlarm(ctx: Context, status: String, title: String, @RawRes soundId: Int) {
val i = Intent(ctx, errorHelperActivity) val i = Intent(ctx, errorHelperActivity)
@ -46,4 +43,10 @@ class ActivityNamesImpl @Inject constructor() : ActivityNames {
}.show(fragmentManager, "Food Item") }.show(fragmentManager, "Food Item")
} }
override fun runProfileSwitchDialog(fragmentManager: FragmentManager, profileName: String?) {
ProfileSwitchDialog()
.also { it.arguments = Bundle().also { bundle -> bundle.putString("profileName", profileName) } }
.show(fragmentManager, "ProfileSwitchDialog")
}
} }

View file

@ -39,8 +39,8 @@ import info.nightscout.androidaps.logging.UserEntryLogger
import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.plugins.general.autotune.data.ATProfile import info.nightscout.androidaps.plugins.general.autotune.data.ATProfile
import info.nightscout.androidaps.plugins.general.autotune.events.EventAutotuneUpdateGui import info.nightscout.androidaps.plugins.general.autotune.events.EventAutotuneUpdateGui
import info.nightscout.androidaps.plugins.profile.local.LocalProfilePlugin import info.nightscout.plugins.profile.ProfilePlugin
import info.nightscout.androidaps.plugins.profile.local.events.EventLocalProfileChanged import info.nightscout.plugins.profile.events.EventLocalProfileChanged
import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.MidnightTime import info.nightscout.androidaps.utils.MidnightTime
@ -63,7 +63,7 @@ class AutotuneFragment : DaggerFragment() {
@Inject lateinit var sp: SP @Inject lateinit var sp: SP
@Inject lateinit var dateUtil: DateUtil @Inject lateinit var dateUtil: DateUtil
@Inject lateinit var activePlugin: ActivePlugin @Inject lateinit var activePlugin: ActivePlugin
@Inject lateinit var localProfilePlugin: LocalProfilePlugin @Inject lateinit var profilePlugin: ProfilePlugin
@Inject lateinit var fabricPrivacy: FabricPrivacy @Inject lateinit var fabricPrivacy: FabricPrivacy
@Inject lateinit var uel: UserEntryLogger @Inject lateinit var uel: UserEntryLogger
@Inject lateinit var rh: ResourceHelper @Inject lateinit var rh: ResourceHelper
@ -134,7 +134,7 @@ class AutotuneFragment : DaggerFragment() {
rh.gs(R.string.autotune_copy_localprofile_button), rh.gs(R.string.autotune_copy_localprofile_button),
rh.gs(R.string.autotune_copy_local_profile_message) + "\n" + localName, rh.gs(R.string.autotune_copy_local_profile_message) + "\n" + localName,
Runnable { Runnable {
localProfilePlugin.addProfile(localProfilePlugin.copyFrom(tunedProfile.getProfile(circadian), localName)) profilePlugin.addProfile(profilePlugin.copyFrom(tunedProfile.getProfile(circadian), localName))
rxBus.send(EventLocalProfileChanged()) rxBus.send(EventLocalProfileChanged())
uel.log( uel.log(
UserEntry.Action.NEW_PROFILE, UserEntry.Action.NEW_PROFILE,

View file

@ -14,8 +14,8 @@ import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.plugins.general.autotune.data.ATProfile import info.nightscout.androidaps.plugins.general.autotune.data.ATProfile
import info.nightscout.androidaps.plugins.general.autotune.data.PreppedGlucose import info.nightscout.androidaps.plugins.general.autotune.data.PreppedGlucose
import info.nightscout.androidaps.plugins.general.autotune.events.EventAutotuneUpdateGui import info.nightscout.androidaps.plugins.general.autotune.events.EventAutotuneUpdateGui
import info.nightscout.androidaps.plugins.profile.local.LocalProfilePlugin import info.nightscout.plugins.profile.ProfilePlugin
import info.nightscout.androidaps.plugins.profile.local.events.EventLocalProfileChanged import info.nightscout.plugins.profile.events.EventLocalProfileChanged
import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.JsonHelper import info.nightscout.androidaps.utils.JsonHelper
import info.nightscout.androidaps.utils.MidnightTime import info.nightscout.androidaps.utils.MidnightTime
@ -46,7 +46,7 @@ class AutotunePlugin @Inject constructor(
private val profileFunction: ProfileFunction, private val profileFunction: ProfileFunction,
private val dateUtil: DateUtil, private val dateUtil: DateUtil,
private val activePlugin: ActivePlugin, private val activePlugin: ActivePlugin,
private val localProfilePlugin: LocalProfilePlugin, private val profilePlugin: ProfilePlugin,
private val autotuneFS: AutotuneFS, private val autotuneFS: AutotuneFS,
private val autotuneIob: AutotuneIob, private val autotuneIob: AutotuneIob,
private val autotunePrep: AutotunePrep, private val autotunePrep: AutotunePrep,
@ -318,15 +318,15 @@ class AutotunePlugin @Inject constructor(
if (profileList[p] == newProfile.profilename) if (profileList[p] == newProfile.profilename)
indexLocalProfile = p indexLocalProfile = p
if (indexLocalProfile == -1) { if (indexLocalProfile == -1) {
localProfilePlugin.addProfile(localProfilePlugin.copyFrom(newProfile.getProfile(circadian), newProfile.profilename)) profilePlugin.addProfile(profilePlugin.copyFrom(newProfile.getProfile(circadian), newProfile.profilename))
return return
} }
localProfilePlugin.currentProfileIndex = indexLocalProfile profilePlugin.currentProfileIndex = indexLocalProfile
localProfilePlugin.currentProfile()?.dia = newProfile.dia profilePlugin.currentProfile()?.dia = newProfile.dia
localProfilePlugin.currentProfile()?.basal = newProfile.basal() profilePlugin.currentProfile()?.basal = newProfile.basal()
localProfilePlugin.currentProfile()?.ic = newProfile.ic(circadian) profilePlugin.currentProfile()?.ic = newProfile.ic(circadian)
localProfilePlugin.currentProfile()?.isf = newProfile.isf(circadian) profilePlugin.currentProfile()?.isf = newProfile.isf(circadian)
localProfilePlugin.storeSettings() profilePlugin.storeSettings()
} }
fun saveLastRun() { fun saveLastRun() {

View file

@ -10,7 +10,7 @@ import info.nightscout.androidaps.interfaces.DataSyncSelector
import info.nightscout.androidaps.interfaces.ProfileFunction import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.AAPSLogger
import info.nightscout.shared.logging.LTag import info.nightscout.shared.logging.LTag
import info.nightscout.androidaps.plugins.profile.local.LocalProfilePlugin import info.nightscout.plugins.profile.ProfilePlugin
import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.shared.sharedPreferences.SP import info.nightscout.shared.sharedPreferences.SP
import javax.inject.Inject import javax.inject.Inject
@ -25,7 +25,7 @@ class DataSyncSelectorImplementation @Inject constructor(
private val nsClientPlugin: NSClientPlugin, private val nsClientPlugin: NSClientPlugin,
private val activePlugin: ActivePlugin, private val activePlugin: ActivePlugin,
private val appRepository: AppRepository, private val appRepository: AppRepository,
private val localProfilePlugin: LocalProfilePlugin private val profilePlugin: ProfilePlugin
) : DataSyncSelector { ) : DataSyncSelector {
class QueueCounter( class QueueCounter(
@ -940,8 +940,8 @@ class DataSyncSelectorImplementation @Inject constructor(
val lastChange = sp.getLong(R.string.key_local_profile_last_change, 0) val lastChange = sp.getLong(R.string.key_local_profile_last_change, 0)
if (lastChange == 0L) return if (lastChange == 0L) return
if (lastChange > lastSync) { if (lastChange > lastSync) {
if (localProfilePlugin.profile?.allProfilesValid != true) return if (profilePlugin.profile?.allProfilesValid != true) return
val profileJson = localProfilePlugin.profile?.data ?: return val profileJson = profilePlugin.profile?.data ?: return
nsClientPlugin.nsClientService?.dbAdd("profile", profileJson, DataSyncSelector.PairProfileStore(profileJson, dateUtil.now()), "") nsClientPlugin.nsClientService?.dbAdd("profile", profileJson, DataSyncSelector.PairProfileStore(profileJson, dateUtil.now()), "")
} }
} }

View file

@ -40,7 +40,7 @@ import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNo
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification import info.nightscout.androidaps.plugins.general.overview.notifications.Notification
import info.nightscout.androidaps.plugins.general.overview.notifications.NotificationWithAction import info.nightscout.androidaps.plugins.general.overview.notifications.NotificationWithAction
import info.nightscout.androidaps.plugins.profile.local.LocalProfilePlugin import info.nightscout.plugins.profile.ProfilePlugin
import info.nightscout.androidaps.plugins.source.NSClientSourcePlugin.NSClientSourceWorker import info.nightscout.androidaps.plugins.source.NSClientSourcePlugin.NSClientSourceWorker
import info.nightscout.androidaps.receivers.DataWorkerStorage import info.nightscout.androidaps.receivers.DataWorkerStorage
import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.DateUtil
@ -467,7 +467,7 @@ class NSClientService : DaggerService() {
val profileStoreJson = profiles[profiles.length() - 1] as JSONObject val profileStoreJson = profiles[profiles.length() - 1] as JSONObject
rxBus.send(EventNSClientNewLog("PROFILE", "profile received")) rxBus.send(EventNSClientNewLog("PROFILE", "profile received"))
dataWorkerStorage.enqueue( dataWorkerStorage.enqueue(
OneTimeWorkRequest.Builder(LocalProfilePlugin.NSProfileWorker::class.java) OneTimeWorkRequest.Builder(ProfilePlugin.NSProfileWorker::class.java)
.setInputData(dataWorkerStorage.storeInputData(profileStoreJson)) .setInputData(dataWorkerStorage.storeInputData(profileStoreJson))
.build() .build()
) )

View file

@ -1,5 +1,6 @@
package info.nightscout.androidaps.plugins.general.overview package info.nightscout.androidaps.plugins.general.overview
import android.content.Context
import androidx.annotation.StringRes import androidx.annotation.StringRes
import androidx.preference.PreferenceFragmentCompat import androidx.preference.PreferenceFragmentCompat
import androidx.preference.SwitchPreference import androidx.preference.SwitchPreference
@ -27,6 +28,7 @@ import info.nightscout.androidaps.plugins.general.overview.notifications.Notific
import info.nightscout.androidaps.plugins.general.overview.notifications.NotificationWithAction import info.nightscout.androidaps.plugins.general.overview.notifications.NotificationWithAction
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventIobCalculationProgress import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventIobCalculationProgress
import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.alertDialogs.OKDialog
import info.nightscout.androidaps.utils.rx.AapsSchedulers import info.nightscout.androidaps.utils.rx.AapsSchedulers
import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.AAPSLogger
import info.nightscout.shared.sharedPreferences.SP import info.nightscout.shared.sharedPreferences.SP
@ -66,6 +68,25 @@ class OverviewPlugin @Inject constructor(
private var disposable: CompositeDisposable = CompositeDisposable() private var disposable: CompositeDisposable = CompositeDisposable()
override val overviewBus = RxBus(aapsSchedulers, aapsLogger) override val overviewBus = RxBus(aapsSchedulers, aapsLogger)
@FunctionalInterface
interface RunnableWithContext : Runnable {
var context: Context?
}
override fun addNotificationWithDialogResponse(id: Int, text: String, level: Int, @StringRes actionButtonId: Int, title: String, message: String) {
rxBus.send(
EventNewNotification(
NotificationWithAction(injector, id, text, level)
.also { n ->
n.action(actionButtonId) {
n.contextForAction?.let { OKDialog.show(it, title, message, null) }
}
})
)
}
override fun addNotification(id: Int, text: String, level: Int, @StringRes actionButtonId: Int, action: Runnable) { override fun addNotification(id: Int, text: String, level: Int, @StringRes actionButtonId: Int, action: Runnable) {
rxBus.send( rxBus.send(
EventNewNotification( EventNewNotification(

View file

@ -27,8 +27,8 @@ import info.nightscout.androidaps.plugins.constraints.objectives.ObjectivesFragm
import info.nightscout.androidaps.plugins.constraints.objectives.ObjectivesPlugin import info.nightscout.androidaps.plugins.constraints.objectives.ObjectivesPlugin
import info.nightscout.androidaps.plugins.general.nsclient.NSClientPlugin import info.nightscout.androidaps.plugins.general.nsclient.NSClientPlugin
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientStatus import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientStatus
import info.nightscout.androidaps.plugins.profile.local.LocalProfileFragment import info.nightscout.plugins.profile.ProfileFragment
import info.nightscout.androidaps.plugins.profile.local.LocalProfilePlugin import info.nightscout.plugins.profile.ProfilePlugin
import info.nightscout.androidaps.plugins.pump.common.events.EventRileyLinkDeviceStatusChange import info.nightscout.androidaps.plugins.pump.common.events.EventRileyLinkDeviceStatusChange
import info.nightscout.androidaps.plugins.pump.omnipod.dash.OmnipodDashPumpPlugin import info.nightscout.androidaps.plugins.pump.omnipod.dash.OmnipodDashPumpPlugin
import info.nightscout.androidaps.plugins.pump.omnipod.eros.OmnipodErosPumpPlugin import info.nightscout.androidaps.plugins.pump.omnipod.eros.OmnipodErosPumpPlugin
@ -62,7 +62,7 @@ class SWDefinition @Inject constructor(
rh: ResourceHelper, rh: ResourceHelper,
private val sp: SP, private val sp: SP,
private val profileFunction: ProfileFunction, private val profileFunction: ProfileFunction,
private val localProfilePlugin: LocalProfilePlugin, private val profilePlugin: ProfilePlugin,
private val activePlugin: ActivePlugin, private val activePlugin: ActivePlugin,
private val commandQueue: CommandQueue, private val commandQueue: CommandQueue,
private val objectivesPlugin: ObjectivesPlugin, private val objectivesPlugin: ObjectivesPlugin,
@ -273,12 +273,12 @@ class SWDefinition @Inject constructor(
private val screenLocalProfile = SWScreen(injector, R.string.localprofile) private val screenLocalProfile = SWScreen(injector, R.string.localprofile)
.skippable(false) .skippable(false)
.add(SWFragment(injector, this) .add(SWFragment(injector, this)
.add(LocalProfileFragment())) .add(ProfileFragment()))
.validator { .validator {
localProfilePlugin.profile?.getDefaultProfile()?.let { ProfileSealed.Pure(it).isValid("StartupWizard", activePlugin.activePump, config, rh, rxBus, hardLimits, false).isValid } profilePlugin.profile?.getDefaultProfile()?.let { ProfileSealed.Pure(it).isValid("StartupWizard", activePlugin.activePump, config, rh, rxBus, hardLimits, false).isValid }
?: false ?: false
} }
.visibility { localProfilePlugin.isEnabled() } .visibility { profilePlugin.isEnabled() }
private val screenProfileSwitch = SWScreen(injector, R.string.careportal_profileswitch) private val screenProfileSwitch = SWScreen(injector, R.string.careportal_profileswitch)
.skippable(false) .skippable(false)
.add(SWInfoText(injector) .add(SWInfoText(injector)

View file

@ -13,9 +13,8 @@ import info.nightscout.androidaps.events.EventProfileSwitchChanged
import info.nightscout.androidaps.events.EventProfileStoreChanged import info.nightscout.androidaps.events.EventProfileStoreChanged
import info.nightscout.androidaps.events.EventPumpStatusChanged import info.nightscout.androidaps.events.EventPumpStatusChanged
import info.nightscout.androidaps.logging.UserEntryLogger import info.nightscout.androidaps.logging.UserEntryLogger
import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientStatus import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientStatus
import info.nightscout.androidaps.plugins.profile.local.LocalProfilePlugin import info.nightscout.plugins.profile.ProfilePlugin
import info.nightscout.androidaps.plugins.pump.common.events.EventRileyLinkDeviceStatusChange import info.nightscout.androidaps.plugins.pump.common.events.EventRileyLinkDeviceStatusChange
import info.nightscout.androidaps.setupwizard.elements.SWItem import info.nightscout.androidaps.setupwizard.elements.SWItem
import info.nightscout.androidaps.setupwizard.events.EventSWUpdate import info.nightscout.androidaps.setupwizard.events.EventSWUpdate
@ -32,7 +31,7 @@ import kotlin.math.min
class SetupWizardActivity : NoSplashAppCompatActivity() { class SetupWizardActivity : NoSplashAppCompatActivity() {
@Inject lateinit var injector: HasAndroidInjector @Inject lateinit var injector: HasAndroidInjector
@Inject lateinit var localProfilePlugin: LocalProfilePlugin @Inject lateinit var profilePlugin: ProfilePlugin
@Inject lateinit var swDefinition: SWDefinition @Inject lateinit var swDefinition: SWDefinition
@Inject lateinit var sp: SP @Inject lateinit var sp: SP
@Inject lateinit var fabricPrivacy: FabricPrivacy @Inject lateinit var fabricPrivacy: FabricPrivacy

View file

@ -2,147 +2,3 @@
package info.nightscout.androidaps.utils.ui package info.nightscout.androidaps.utils.ui
import android.view.MotionEvent
import android.view.View
import android.widget.AdapterView
import android.widget.Spinner
import android.widget.SpinnerAdapter
import kotlin.math.max
/**
* Spinner Helper class that works around some common issues
* with the stock Android Spinner
*
* A Spinner will normally call it's OnItemSelectedListener
* when you use setSelection(...) in your initialization code.
* This is usually unwanted behavior, and a common work-around
* is to use spinner.post(...) with a Runnable to assign the
* OnItemSelectedListener after layout.
*
* If you do not call setSelection(...) manually, the callback
* may be called with the first item in the adapter you have
* set. The common work-around for that is to count callbacks.
*
* While these workarounds usually *seem* to work, the callback
* may still be called repeatedly for other reasons while the
* selection hasn't actually changed. This will happen for
* example, if the user has accessibility options enabled -
* which is more common than you might think as several apps
* use this for different purposes, like detecting which
* notifications are active.
*
* Ideally, your OnItemSelectedListener callback should be
* coded defensively so that no problem would occur even
* if the callback was called repeatedly with the same values
* without any user interaction, so no workarounds are needed.
*
* This class does that for you. It keeps track of the values
* you have set with the setSelection(...) methods, and
* proxies the OnItemSelectedListener callback so your callback
* only gets called if the selected item's position differs
* from the one you have set by code, or the first item if you
* did not set it.
*
* This also means that if the user actually clicks the item
* that was previously selected by code (or the first item
* if you didn't set a selection by code), the callback will
* not fire.
*
* To implement, replace current occurrences of:
*
* Spinner spinner =
* (Spinner)findViewById(R.id.xxx);
*
* with:
*
* SpinnerHelper spinner =
* new SpinnerHelper(findViewById(R.id.xxx))
*
* SpinnerHelper proxies the (my) most used calls to Spinner
* but not all of them. Should a method not be available, use:
*
* spinner.getSpinner().someMethod(...)
*
* Or just add the proxy method yourself :)
*
* (Quickly) Tested on devices from 2.3.6 through 4.2.2
*
* @author Jorrit "Chainfire" Jongma
* @license WTFPL (do whatever you want with this, nobody cares)
*/
@Suppress("unused")
class SpinnerHelper(val spinner: Spinner) : AdapterView.OnItemSelectedListener {
private var userTouched = false
private var lastPosition = -1
private var proxiedItemSelectedListener: AdapterView.OnItemSelectedListener? = null
fun setSelection(position: Int) {
lastPosition = max(-1, position)
spinner.setSelection(position)
}
fun setSelection(position: Int, animate: Boolean) {
lastPosition = max(-1, position)
spinner.setSelection(position, animate)
}
fun setOnItemSelectedListener(listener: AdapterView.OnItemSelectedListener?) {
proxiedItemSelectedListener = listener
setTouchListener()
spinner.onItemSelectedListener = if (listener == null) null else this
}
private fun setTouchListener() {
spinner.setOnTouchListener { v: View, _: MotionEvent? ->
v.performClick()
userTouched = true
false
}
}
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
if (position != lastPosition && userTouched) {
lastPosition = position
proxiedItemSelectedListener?.onItemSelected(parent, view, position, id)
}
}
override fun onNothingSelected(parent: AdapterView<*>?) {
if (lastPosition != -1) {
lastPosition = -1
proxiedItemSelectedListener?.onNothingSelected(parent)
}
}
var adapter: SpinnerAdapter
get() = spinner.adapter
set(adapter) {
if (adapter.count > 0) {
lastPosition = 0
}
spinner.adapter = adapter
}
val count: Int
get() = spinner.count
fun getItemAtPosition(position: Int): Any = spinner.getItemAtPosition(position)
fun getItemIdAtPosition(position: Int): Long = spinner.getItemIdAtPosition(position)
val selectedItem: Any
get() = try {
spinner.selectedItem
} catch (e: IndexOutOfBoundsException) {
adapter.getItem(adapter.count - 1)
}
val selectedItemId: Long
get() = spinner.selectedItemId
val selectedItemPosition: Int
get() = spinner.selectedItemPosition
var isEnabled: Boolean
get() = spinner.isEnabled
set(enabled) {
spinner.isEnabled = enabled
}
}

View file

@ -88,7 +88,7 @@
android:drawableTop="@drawable/ic_calculator" android:drawableTop="@drawable/ic_calculator"
android:ellipsize="end" android:ellipsize="end"
android:singleLine="true" android:singleLine="true"
android:text="@string/overview_calculator_label" android:text="@string/calculator_label"
android:textColor="?attr/icCalculatorColor" android:textColor="?attr/icCalculatorColor"
app:iconPadding="-4dp" /> app:iconPadding="-4dp" />

View file

@ -78,7 +78,7 @@
<string name="constraints_violation">Beperkings skending</string> <string name="constraints_violation">Beperkings skending</string>
<string name="setbasalquestion">Aanvaar nuwe tydelike basale:</string> <string name="setbasalquestion">Aanvaar nuwe tydelike basale:</string>
<string name="overview_treatment_label">Behandeling</string> <string name="overview_treatment_label">Behandeling</string>
<string name="overview_calculator_label">Rekenaar</string> <string name="calculator_label">Rekenaar</string>
<string name="changeyourinput">Verander jou insette!</string> <string name="changeyourinput">Verander jou insette!</string>
<string name="configbuilder_bgsource">BG bron</string> <string name="configbuilder_bgsource">BG bron</string>
<string name="apsmode_title">APS modus</string> <string name="apsmode_title">APS modus</string>

View file

@ -84,7 +84,7 @@
<string name="constraints_violation">Нарушено ограничение</string> <string name="constraints_violation">Нарушено ограничение</string>
<string name="setbasalquestion">Приложи нов временен базал:</string> <string name="setbasalquestion">Приложи нов временен базал:</string>
<string name="overview_treatment_label">Болус</string> <string name="overview_treatment_label">Болус</string>
<string name="overview_calculator_label">Калкулатор</string> <string name="calculator_label">Калкулатор</string>
<string name="changeyourinput">Променете данните!</string> <string name="changeyourinput">Променете данните!</string>
<string name="configbuilder_bgsource">Източник на данни за КЗ</string> <string name="configbuilder_bgsource">Източник на данни за КЗ</string>
<string name="xdrip">xDrip+</string> <string name="xdrip">xDrip+</string>

View file

@ -82,7 +82,7 @@
<string name="constraints_violation">Violació de restriccions</string> <string name="constraints_violation">Violació de restriccions</string>
<string name="setbasalquestion">Acceptar nova basal temporal:</string> <string name="setbasalquestion">Acceptar nova basal temporal:</string>
<string name="overview_treatment_label">Tractament</string> <string name="overview_treatment_label">Tractament</string>
<string name="overview_calculator_label">Calculadora</string> <string name="calculator_label">Calculadora</string>
<string name="changeyourinput">Modifiqueu les dades!</string> <string name="changeyourinput">Modifiqueu les dades!</string>
<string name="configbuilder_bgsource">Origen glucèmia</string> <string name="configbuilder_bgsource">Origen glucèmia</string>
<string name="xdrip">xDrip+</string> <string name="xdrip">xDrip+</string>

View file

@ -89,7 +89,7 @@
<string name="constraints_violation">Mimo povolený rozsah</string> <string name="constraints_violation">Mimo povolený rozsah</string>
<string name="setbasalquestion">Spustit nový dočasný bazál:</string> <string name="setbasalquestion">Spustit nový dočasný bazál:</string>
<string name="overview_treatment_label">Bolus</string> <string name="overview_treatment_label">Bolus</string>
<string name="overview_calculator_label">Kalkulačka</string> <string name="calculator_label">Kalkulačka</string>
<string name="changeyourinput">Změňte zadání!</string> <string name="changeyourinput">Změňte zadání!</string>
<string name="configbuilder_bgsource">Zdroj glykémie</string> <string name="configbuilder_bgsource">Zdroj glykémie</string>
<string name="configbuilder_bgsource_description">Odkud má AAPS získávat glykémie?</string> <string name="configbuilder_bgsource_description">Odkud má AAPS získávat glykémie?</string>

View file

@ -85,7 +85,7 @@
<string name="constraints_violation">Begrænsninger overtrådt</string> <string name="constraints_violation">Begrænsninger overtrådt</string>
<string name="setbasalquestion">Acceptér ny midlertidig basal:</string> <string name="setbasalquestion">Acceptér ny midlertidig basal:</string>
<string name="overview_treatment_label">Behandling</string> <string name="overview_treatment_label">Behandling</string>
<string name="overview_calculator_label">Beregner</string> <string name="calculator_label">Beregner</string>
<string name="changeyourinput">Skift dit input!</string> <string name="changeyourinput">Skift dit input!</string>
<string name="configbuilder_bgsource">BG kilde</string> <string name="configbuilder_bgsource">BG kilde</string>
<string name="xdrip">xDrip+</string> <string name="xdrip">xDrip+</string>

View file

@ -85,7 +85,7 @@
<string name="constraints_violation">Beschränkungen wurden verletzt oder Limit erreicht.</string> <string name="constraints_violation">Beschränkungen wurden verletzt oder Limit erreicht.</string>
<string name="setbasalquestion">Akzeptiere neue TBR:</string> <string name="setbasalquestion">Akzeptiere neue TBR:</string>
<string name="overview_treatment_label">Bolus</string> <string name="overview_treatment_label">Bolus</string>
<string name="overview_calculator_label">Rechner</string> <string name="calculator_label">Rechner</string>
<string name="changeyourinput">Ändere deine Eingabe!</string> <string name="changeyourinput">Ändere deine Eingabe!</string>
<string name="configbuilder_bgsource">BZ-Quelle</string> <string name="configbuilder_bgsource">BZ-Quelle</string>
<string name="xdrip">xDrip+</string> <string name="xdrip">xDrip+</string>

View file

@ -79,7 +79,7 @@
<string name="constraints_violation">Παραβίαση Περιορισμών</string> <string name="constraints_violation">Παραβίαση Περιορισμών</string>
<string name="setbasalquestion">Αποδοχή νέου Προσ Ρυθμού:</string> <string name="setbasalquestion">Αποδοχή νέου Προσ Ρυθμού:</string>
<string name="overview_treatment_label">Θεραπεία</string> <string name="overview_treatment_label">Θεραπεία</string>
<string name="overview_calculator_label">Υπολογιστής</string> <string name="calculator_label">Υπολογιστής</string>
<string name="changeyourinput">Αλλάξτε αυτό που εισάγατε!</string> <string name="changeyourinput">Αλλάξτε αυτό που εισάγατε!</string>
<string name="configbuilder_bgsource">Πηγή BG</string> <string name="configbuilder_bgsource">Πηγή BG</string>
<string name="apsmode_title">Λειτουργία APS</string> <string name="apsmode_title">Λειτουργία APS</string>

View file

@ -89,7 +89,7 @@
<string name="constraints_violation">Violación de restricciones</string> <string name="constraints_violation">Violación de restricciones</string>
<string name="setbasalquestion">Aceptar nueva basal temporal:</string> <string name="setbasalquestion">Aceptar nueva basal temporal:</string>
<string name="overview_treatment_label">Tratamiento</string> <string name="overview_treatment_label">Tratamiento</string>
<string name="overview_calculator_label">Calculadora</string> <string name="calculator_label">Calculadora</string>
<string name="changeyourinput">¡Cambiar datos!</string> <string name="changeyourinput">¡Cambiar datos!</string>
<string name="configbuilder_bgsource">Origen de Glucosa</string> <string name="configbuilder_bgsource">Origen de Glucosa</string>
<string name="configbuilder_bgsource_description">¿Desde dónde debería obtener AAPS los datos?</string> <string name="configbuilder_bgsource_description">¿Desde dónde debería obtener AAPS los datos?</string>

View file

@ -89,7 +89,7 @@
<string name="constraints_violation">Violation des restrictions</string> <string name="constraints_violation">Violation des restrictions</string>
<string name="setbasalquestion">Accepter nouveau basal temporaire :</string> <string name="setbasalquestion">Accepter nouveau basal temporaire :</string>
<string name="overview_treatment_label">Traitement</string> <string name="overview_treatment_label">Traitement</string>
<string name="overview_calculator_label">Assistant</string> <string name="calculator_label">Assistant</string>
<string name="changeyourinput">Changez vos entrées !</string> <string name="changeyourinput">Changez vos entrées !</string>
<string name="configbuilder_bgsource">Source des glycémies</string> <string name="configbuilder_bgsource">Source des glycémies</string>
<string name="configbuilder_bgsource_description">Quelle source de données doit être utilisée par AAPS ?</string> <string name="configbuilder_bgsource_description">Quelle source de données doit être utilisée par AAPS ?</string>

View file

@ -89,7 +89,7 @@
<string name="constraints_violation">Violazione dei vincoli</string> <string name="constraints_violation">Violazione dei vincoli</string>
<string name="setbasalquestion">Accetta nuova basale temporanea:</string> <string name="setbasalquestion">Accetta nuova basale temporanea:</string>
<string name="overview_treatment_label">Trattamento</string> <string name="overview_treatment_label">Trattamento</string>
<string name="overview_calculator_label">Calcolatore</string> <string name="calculator_label">Calcolatore</string>
<string name="changeyourinput">Cambia il tuo input!</string> <string name="changeyourinput">Cambia il tuo input!</string>
<string name="configbuilder_bgsource">Origine BG</string> <string name="configbuilder_bgsource">Origine BG</string>
<string name="configbuilder_bgsource_description">Da dove AAPS dovrebbe ottenere i suoi dati?</string> <string name="configbuilder_bgsource_description">Da dove AAPS dovrebbe ottenere i suoi dati?</string>

View file

@ -85,7 +85,7 @@
<string name="constraints_violation">הפרת מגבלות</string> <string name="constraints_violation">הפרת מגבלות</string>
<string name="setbasalquestion">אשר בזאלי זמני חדש:</string> <string name="setbasalquestion">אשר בזאלי זמני חדש:</string>
<string name="overview_treatment_label">טיפול</string> <string name="overview_treatment_label">טיפול</string>
<string name="overview_calculator_label">מחשבון</string> <string name="calculator_label">מחשבון</string>
<string name="changeyourinput">שנה קלט!</string> <string name="changeyourinput">שנה קלט!</string>
<string name="configbuilder_bgsource">מקור ערכי הסוכר</string> <string name="configbuilder_bgsource">מקור ערכי הסוכר</string>
<string name="xdrip">xDrip+</string> <string name="xdrip">xDrip+</string>

View file

@ -82,7 +82,7 @@
<string name="constraints_violation">제한 위반</string> <string name="constraints_violation">제한 위반</string>
<string name="setbasalquestion">새 임시Basal 적용:</string> <string name="setbasalquestion">새 임시Basal 적용:</string>
<string name="overview_treatment_label">관리</string> <string name="overview_treatment_label">관리</string>
<string name="overview_calculator_label">계산기</string> <string name="calculator_label">계산기</string>
<string name="changeyourinput">입력값을 변경하세요!</string> <string name="changeyourinput">입력값을 변경하세요!</string>
<string name="configbuilder_bgsource">혈당 출처</string> <string name="configbuilder_bgsource">혈당 출처</string>
<string name="xdrip">xDrip+</string> <string name="xdrip">xDrip+</string>

View file

@ -83,7 +83,7 @@
<string name="constraints_violation">Apribojimų pažeidimas</string> <string name="constraints_violation">Apribojimų pažeidimas</string>
<string name="setbasalquestion">Patvirtinti naują laikiną bazę:</string> <string name="setbasalquestion">Patvirtinti naują laikiną bazę:</string>
<string name="overview_treatment_label">Terapija</string> <string name="overview_treatment_label">Terapija</string>
<string name="overview_calculator_label">Skaičiuotuvas</string> <string name="calculator_label">Skaičiuotuvas</string>
<string name="changeyourinput">Pakeiskite įvestus duomenis!</string> <string name="changeyourinput">Pakeiskite įvestus duomenis!</string>
<string name="configbuilder_bgsource">Glikemijos šaltinis</string> <string name="configbuilder_bgsource">Glikemijos šaltinis</string>
<string name="xdrip">xDrip+</string> <string name="xdrip">xDrip+</string>

View file

@ -85,7 +85,7 @@
<string name="constraints_violation">In strijd met beperkingen</string> <string name="constraints_violation">In strijd met beperkingen</string>
<string name="setbasalquestion">Accepteer nieuw tijdelijk basaal:</string> <string name="setbasalquestion">Accepteer nieuw tijdelijk basaal:</string>
<string name="overview_treatment_label">Bolus</string> <string name="overview_treatment_label">Bolus</string>
<string name="overview_calculator_label">Bolus wizard</string> <string name="calculator_label">Bolus wizard</string>
<string name="changeyourinput">Wijzig het ingegevene!</string> <string name="changeyourinput">Wijzig het ingegevene!</string>
<string name="configbuilder_bgsource">BG bron</string> <string name="configbuilder_bgsource">BG bron</string>
<string name="xdrip">xDrip+</string> <string name="xdrip">xDrip+</string>

View file

@ -89,7 +89,7 @@
<string name="constraints_violation">Brudd på begrensninger</string> <string name="constraints_violation">Brudd på begrensninger</string>
<string name="setbasalquestion">Aksepter ny temp basal:</string> <string name="setbasalquestion">Aksepter ny temp basal:</string>
<string name="overview_treatment_label">Behandling</string> <string name="overview_treatment_label">Behandling</string>
<string name="overview_calculator_label">Kalkulator</string> <string name="calculator_label">Kalkulator</string>
<string name="changeyourinput">Endre dine inndata!</string> <string name="changeyourinput">Endre dine inndata!</string>
<string name="configbuilder_bgsource">BS-kilde</string> <string name="configbuilder_bgsource">BS-kilde</string>
<string name="configbuilder_bgsource_description">Hvor skal AAPS få sine data fra?</string> <string name="configbuilder_bgsource_description">Hvor skal AAPS få sine data fra?</string>

View file

@ -83,7 +83,7 @@
<string name="constraints_violation">Naruszenie ograniczeń</string> <string name="constraints_violation">Naruszenie ograniczeń</string>
<string name="setbasalquestion">Akceptuj nową bazę tymczasową:</string> <string name="setbasalquestion">Akceptuj nową bazę tymczasową:</string>
<string name="overview_treatment_label">Terapia</string> <string name="overview_treatment_label">Terapia</string>
<string name="overview_calculator_label">Kalkulator</string> <string name="calculator_label">Kalkulator</string>
<string name="changeyourinput">Zmień wprowadzone dane!</string> <string name="changeyourinput">Zmień wprowadzone dane!</string>
<string name="configbuilder_bgsource">Źródło BG</string> <string name="configbuilder_bgsource">Źródło BG</string>
<string name="xdrip">xDrip+</string> <string name="xdrip">xDrip+</string>

View file

@ -84,7 +84,7 @@
<string name="constraints_violation">Violação das restrições</string> <string name="constraints_violation">Violação das restrições</string>
<string name="setbasalquestion">Aceitar nova basal temporária:</string> <string name="setbasalquestion">Aceitar nova basal temporária:</string>
<string name="overview_treatment_label">Tratamento</string> <string name="overview_treatment_label">Tratamento</string>
<string name="overview_calculator_label">Calculadora</string> <string name="calculator_label">Calculadora</string>
<string name="changeyourinput">Altere sua entrada!</string> <string name="changeyourinput">Altere sua entrada!</string>
<string name="configbuilder_bgsource">Fonte de BG</string> <string name="configbuilder_bgsource">Fonte de BG</string>
<string name="xdrip">xDrip+</string> <string name="xdrip">xDrip+</string>

View file

@ -83,7 +83,7 @@
<string name="constraints_violation">Violação das restrições</string> <string name="constraints_violation">Violação das restrições</string>
<string name="setbasalquestion">Aceitar nova basal temporária:</string> <string name="setbasalquestion">Aceitar nova basal temporária:</string>
<string name="overview_treatment_label">Tratamento</string> <string name="overview_treatment_label">Tratamento</string>
<string name="overview_calculator_label">Calculadora</string> <string name="calculator_label">Calculadora</string>
<string name="changeyourinput">Altere o seu input!</string> <string name="changeyourinput">Altere o seu input!</string>
<string name="configbuilder_bgsource">Fonte da Glicose</string> <string name="configbuilder_bgsource">Fonte da Glicose</string>
<string name="xdrip">xDrip+</string> <string name="xdrip">xDrip+</string>

View file

@ -83,7 +83,7 @@
<string name="constraints_violation">Încălcare a unei limite</string> <string name="constraints_violation">Încălcare a unei limite</string>
<string name="setbasalquestion">Acceptă noua bazală temporară:</string> <string name="setbasalquestion">Acceptă noua bazală temporară:</string>
<string name="overview_treatment_label">Tratament</string> <string name="overview_treatment_label">Tratament</string>
<string name="overview_calculator_label">Calculator</string> <string name="calculator_label">Calculator</string>
<string name="changeyourinput">Schimbați ceea ce ați introdus!</string> <string name="changeyourinput">Schimbați ceea ce ați introdus!</string>
<string name="configbuilder_bgsource">Sursă glicemie</string> <string name="configbuilder_bgsource">Sursă glicemie</string>
<string name="xdrip">xDrip+</string> <string name="xdrip">xDrip+</string>

View file

@ -89,7 +89,7 @@
<string name="constraints_violation">ограничение нарушено</string> <string name="constraints_violation">ограничение нарушено</string>
<string name="setbasalquestion">принять новый врем базал:</string> <string name="setbasalquestion">принять новый врем базал:</string>
<string name="overview_treatment_label">болюс</string> <string name="overview_treatment_label">болюс</string>
<string name="overview_calculator_label">калькулятор</string> <string name="calculator_label">калькулятор</string>
<string name="changeyourinput">измените введенные данные</string> <string name="changeyourinput">измените введенные данные</string>
<string name="configbuilder_bgsource">источник СК</string> <string name="configbuilder_bgsource">источник СК</string>
<string name="configbuilder_bgsource_description">Откуда должен получать данные AAPS?</string> <string name="configbuilder_bgsource_description">Откуда должен получать данные AAPS?</string>

View file

@ -89,7 +89,7 @@
<string name="constraints_violation">Mimo povolený rozsah</string> <string name="constraints_violation">Mimo povolený rozsah</string>
<string name="setbasalquestion">Povoliť nový dočasný bazál:</string> <string name="setbasalquestion">Povoliť nový dočasný bazál:</string>
<string name="overview_treatment_label">Bolus</string> <string name="overview_treatment_label">Bolus</string>
<string name="overview_calculator_label">Kalkulačka</string> <string name="calculator_label">Kalkulačka</string>
<string name="changeyourinput">Zmeňte zadanie!</string> <string name="changeyourinput">Zmeňte zadanie!</string>
<string name="configbuilder_bgsource">Zdroj glykémie</string> <string name="configbuilder_bgsource">Zdroj glykémie</string>
<string name="configbuilder_bgsource_description">Odkiaľ má AndroidAPS získavať glykémie?</string> <string name="configbuilder_bgsource_description">Odkiaľ má AndroidAPS získavať glykémie?</string>

View file

@ -85,7 +85,7 @@ Eversense-appen.</string>
<string name="constraints_violation">Begränsning nådd</string> <string name="constraints_violation">Begränsning nådd</string>
<string name="setbasalquestion">Acceptera ny temp basal:</string> <string name="setbasalquestion">Acceptera ny temp basal:</string>
<string name="overview_treatment_label">Behandling</string> <string name="overview_treatment_label">Behandling</string>
<string name="overview_calculator_label">Kalkylator</string> <string name="calculator_label">Kalkylator</string>
<string name="changeyourinput">Ändra inmatning</string> <string name="changeyourinput">Ändra inmatning</string>
<string name="configbuilder_bgsource">BG-källa</string> <string name="configbuilder_bgsource">BG-källa</string>
<string name="xdrip">xDrip+</string> <string name="xdrip">xDrip+</string>

View file

@ -89,7 +89,7 @@
<string name="constraints_violation">Kısıtlamalar ihlali</string> <string name="constraints_violation">Kısıtlamalar ihlali</string>
<string name="setbasalquestion">Yeni geçici bazal oranını kabul et:</string> <string name="setbasalquestion">Yeni geçici bazal oranını kabul et:</string>
<string name="overview_treatment_label">Tedavi</string> <string name="overview_treatment_label">Tedavi</string>
<string name="overview_calculator_label">Hesap makinesi</string> <string name="calculator_label">Hesap makinesi</string>
<string name="changeyourinput">Girişinizi değiştirin!</string> <string name="changeyourinput">Girişinizi değiştirin!</string>
<string name="configbuilder_bgsource">KŞ kaynağı</string> <string name="configbuilder_bgsource">KŞ kaynağı</string>
<string name="configbuilder_bgsource_description">AAPS verilerini nereden alsın?</string> <string name="configbuilder_bgsource_description">AAPS verilerini nereden alsın?</string>

View file

@ -84,7 +84,7 @@
<string name="constraints_violation">违反约束条件</string> <string name="constraints_violation">违反约束条件</string>
<string name="setbasalquestion">接受新的临时基础率</string> <string name="setbasalquestion">接受新的临时基础率</string>
<string name="overview_treatment_label">治疗</string> <string name="overview_treatment_label">治疗</string>
<string name="overview_calculator_label">计算器</string> <string name="calculator_label">计算器</string>
<string name="changeyourinput">更改您的输入!</string> <string name="changeyourinput">更改您的输入!</string>
<string name="configbuilder_bgsource">血糖来源</string> <string name="configbuilder_bgsource">血糖来源</string>
<string name="xdrip">xDrip+</string> <string name="xdrip">xDrip+</string>

View file

@ -52,7 +52,6 @@
<string name="key_ns_effective_profile_switch_last_synced_id" translatable="false">ns_effective_profile_switch_last_synced_id</string> <string name="key_ns_effective_profile_switch_last_synced_id" translatable="false">ns_effective_profile_switch_last_synced_id</string>
<string name="key_ns_offline_event_last_synced_id" translatable="false">ns_offline_event_last_synced_id</string> <string name="key_ns_offline_event_last_synced_id" translatable="false">ns_offline_event_last_synced_id</string>
<string name="key_ns_profile_store_last_synced_timestamp" translatable="false">ns_profile_store_last_synced_timestamp</string> <string name="key_ns_profile_store_last_synced_timestamp" translatable="false">ns_profile_store_last_synced_timestamp</string>
<string name="key_local_profile_last_change" translatable="false">local_profile_last_change</string>
<string name="key_ns_sync_slow" translatable="false">ns_sync_slow</string> <string name="key_ns_sync_slow" translatable="false">ns_sync_slow</string>
<string name="key_last_cleanup_run" translatable="false">last_cleanup_run</string> <string name="key_last_cleanup_run" translatable="false">last_cleanup_run</string>
<string name="treatmentssafety_title">Treatments safety</string> <string name="treatmentssafety_title">Treatments safety</string>
@ -75,7 +74,6 @@
<string name="description_smb_dynamic_isf">Most recent algorithm for advanced users with dynamic/automatic ISF</string> <string name="description_smb_dynamic_isf">Most recent algorithm for advanced users with dynamic/automatic ISF</string>
<string name="description_overview">Displays the current state of your loop and buttons for most common actions</string> <string name="description_overview">Displays the current state of your loop and buttons for most common actions</string>
<string name="description_persistent_notification">Shows an ongoing notification with a short overview of what your loop is doing</string> <string name="description_persistent_notification">Shows an ongoing notification with a short overview of what your loop is doing</string>
<string name="description_profile_local">Define a profile which is available offline.</string>
<string name="description_pump_virtual">Pump integration for pumps which don\'t have any driver yet (Open Loop)</string> <string name="description_pump_virtual">Pump integration for pumps which don\'t have any driver yet (Open Loop)</string>
<string name="description_sensitivity_aaps">Sensitivity is calculated the same way like Oref0, but you can specify timeframe to the past. Minimal carb absorption is calculated from max carb absorption time from preferences.</string> <string name="description_sensitivity_aaps">Sensitivity is calculated the same way like Oref0, but you can specify timeframe to the past. Minimal carb absorption is calculated from max carb absorption time from preferences.</string>
<string name="description_sensitivity_oref1">Sensitivity is calculated from 8h or 24h data in the past (using either which is more sensitive). Carbs (if not absorbed) are cut after time specified in preferences. Plugin also calculates UAM.</string> <string name="description_sensitivity_oref1">Sensitivity is calculated from 8h or 24h data in the past (using either which is more sensitive). Carbs (if not absorbed) are cut after time specified in preferences. Plugin also calculates UAM.</string>
@ -139,7 +137,6 @@
<string name="constraints_violation">Constraints violation</string> <string name="constraints_violation">Constraints violation</string>
<string name="setbasalquestion">Accept new temp basal:</string> <string name="setbasalquestion">Accept new temp basal:</string>
<string name="overview_treatment_label">Treatment</string> <string name="overview_treatment_label">Treatment</string>
<string name="overview_calculator_label">Calculator</string>
<string name="changeyourinput">Change your input!</string> <string name="changeyourinput">Change your input!</string>
<string name="configbuilder_bgsource">BG Source</string> <string name="configbuilder_bgsource">BG Source</string>
<string name="configbuilder_bgsource_description">Where should AAPS gain it\'s data from?</string> <string name="configbuilder_bgsource_description">Where should AAPS gain it\'s data from?</string>
@ -211,7 +208,6 @@
<string name="button1">Button 1</string> <string name="button1">Button 1</string>
<string name="button2">Button 2</string> <string name="button2">Button 2</string>
<string name="button3">Button 3</string> <string name="button3">Button 3</string>
<string name="units_colon">Units:</string>
<string name="units">Units</string> <string name="units">Units</string>
<string name="prefs_range_title">Range for Visualization</string> <string name="prefs_range_title">Range for Visualization</string>
<string name="prefs_range_summary">High and low mark for the charts in Overview and Smartwatch</string> <string name="prefs_range_summary">High and low mark for the charts in Overview and Smartwatch</string>
@ -224,7 +220,6 @@
<string name="MM640g">MM640g</string> <string name="MM640g">MM640g</string>
<string name="ongoingnotificaction">Ongoing Notification</string> <string name="ongoingnotificaction">Ongoing Notification</string>
<string name="old_data">OLD DATA</string> <string name="old_data">OLD DATA</string>
<string name="localprofile">Profile</string>
<string name="openapsama">OpenAPS AMA</string> <string name="openapsama">OpenAPS AMA</string>
<string name="array_of_elements">Array of %1$d elements.\nActual value:</string> <string name="array_of_elements">Array of %1$d elements.\nActual value:</string>
<string name="openapsma_autosensdata_label">Autosens data</string> <string name="openapsma_autosensdata_label">Autosens data</string>
@ -237,7 +232,6 @@
<string name="loop_shortname">LOOP</string> <string name="loop_shortname">LOOP</string>
<string name="oaps_shortname">OAPS</string> <string name="oaps_shortname">OAPS</string>
<string name="dynisf_shortname">DYNISF</string> <string name="dynisf_shortname">DYNISF</string>
<string name="localprofile_shortname">LP</string>
<string name="overview_shortname">HOME</string> <string name="overview_shortname">HOME</string>
<string name="virtualpump_shortname">VPUMP</string> <string name="virtualpump_shortname">VPUMP</string>
<string name="treatments_shortname">TREAT</string> <string name="treatments_shortname">TREAT</string>
@ -392,7 +386,6 @@
<string name="absorption_maxtime_summary">Time in hours where is expected all carbs from meal will be absorbed</string> <string name="absorption_maxtime_summary">Time in hours where is expected all carbs from meal will be absorbed</string>
<string name="openaps_short">OAPS</string> <string name="openaps_short">OAPS</string>
<string name="uploader_short">UPLD</string> <string name="uploader_short">UPLD</string>
<string name="basal_short">BAS</string>
<string name="keep_screen_on_title">Keep screen on</string> <string name="keep_screen_on_title">Keep screen on</string>
<string name="keep_screen_on_summary">Prevent Android to turn screen off. It will consume lot of energy when not plugged to power outlet.</string> <string name="keep_screen_on_summary">Prevent Android to turn screen off. It will consume lot of energy when not plugged to power outlet.</string>
<string name="sensitivity_warning">By turning on Autosense feature remember to enter all eated carbs. Otherwise carbs deviations will be identified wrong as sensitivity change !!</string> <string name="sensitivity_warning">By turning on Autosense feature remember to enter all eated carbs. Otherwise carbs deviations will be identified wrong as sensitivity change !!</string>
@ -413,7 +406,6 @@
<string name="enablesmb">Enable SMB</string> <string name="enablesmb">Enable SMB</string>
<string name="enablesmb_summary">Use Super Micro Boluses instead of temp basal for faster action</string> <string name="enablesmb_summary">Use Super Micro Boluses instead of temp basal for faster action</string>
<string name="enableuam_summary">Detection of Unannounced meals</string> <string name="enableuam_summary">Detection of Unannounced meals</string>
<string name="activate_profile">Activate profile</string>
<string name="invalid">INVALID</string> <string name="invalid">INVALID</string>
<string name="key_wizard_include_cob" translatable="false">wizard_include_cob</string> <string name="key_wizard_include_cob" translatable="false">wizard_include_cob</string>
<string name="key_wizard_include_trend_bg" translatable="false">wizard_include_trend_bg</string> <string name="key_wizard_include_trend_bg" translatable="false">wizard_include_trend_bg</string>
@ -526,8 +518,6 @@
<string name="g5appnotdetected">Please update your Dexcom app to supported version</string> <string name="g5appnotdetected">Please update your Dexcom app to supported version</string>
<string name="dexcom_app_not_installed">Dexcom app is not installed.</string> <string name="dexcom_app_not_installed">Dexcom app is not installed.</string>
<string name="do_not_bolus_record_only">Do not bolus, record only</string> <string name="do_not_bolus_record_only">Do not bolus, record only</string>
<string name="category">Category</string>
<string name="subcategory">Subcategory</string>
<string name="bolusrecordedonly">Bolus will be recorded only (not delivered by pump)</string> <string name="bolusrecordedonly">Bolus will be recorded only (not delivered by pump)</string>
<string name="loop_smbsetbypump_label">SMB set by pump</string> <string name="loop_smbsetbypump_label">SMB set by pump</string>
<string name="overview_show_activity">Activity</string> <string name="overview_show_activity">Activity</string>
@ -756,10 +746,8 @@
<string name="format_carbs_ic">%1$.0fg IC: %2$.1f</string> <string name="format_carbs_ic">%1$.0fg IC: %2$.1f</string>
<string name="format_cob_ic">%1$.1fg IC: %2$.1f</string> <string name="format_cob_ic">%1$.1fg IC: %2$.1f</string>
<string name="format_percent">%1$d%%</string> <string name="format_percent">%1$d%%</string>
<string name="profile_name">Profile name:</string>
<string name="selected_profile">Selected:</string> <string name="selected_profile">Selected:</string>
<string name="unitsnosemicolon">Units</string> <string name="unitsnosemicolon">Units</string>
<string name="doyouwantswitchprofile">Do you want to switch profile and discard changes made to current profile?</string>
<string name="key_wizard_calculation_visible" translatable="false">wizard_calculation_visible</string> <string name="key_wizard_calculation_visible" translatable="false">wizard_calculation_visible</string>
<string name="key_wizard_correction_percent" translatable="false">wizard_correction_percent</string> <string name="key_wizard_correction_percent" translatable="false">wizard_correction_percent</string>
<string name="objectives_button_unfinish">Clear finished</string> <string name="objectives_button_unfinish">Clear finished</string>
@ -768,15 +756,7 @@
<string name="setupwizard_units_prompt">Select units you want to display values in</string> <string name="setupwizard_units_prompt">Select units you want to display values in</string>
<string name="key_wear_detailediob" translatable="false">wear_detailediob</string> <string name="key_wear_detailediob" translatable="false">wear_detailediob</string>
<string name="key_wear_showbgi" translatable="false">wear_showbgi</string> <string name="key_wear_showbgi" translatable="false">wear_showbgi</string>
<string name="dia_short">DIA</string>
<string name="ic_short">IC</string>
<string name="isf_short">ISF</string>
<string name="target_short">TARG</string>
<string name="clone_label">Clone</string>
<string name="saveorresetchangesfirst">Save or reset current changes first</string>
<string name="deletecurrentprofile">Delete current profile?</string>
<string name="copytolocalprofile">Create new profile from this profile?</string> <string name="copytolocalprofile">Create new profile from this profile?</string>
<string name="profilenamecontainsdot">Profile name contains dots.\nThis is not supported by NS.\nProfile is not uploaded to NS.</string>
<string name="low_mark_comment">Lower value of in range area (display only)</string> <string name="low_mark_comment">Lower value of in range area (display only)</string>
<string name="high_mark_comment">Higher value of in range area (display only)</string> <string name="high_mark_comment">Higher value of in range area (display only)</string>
<string name="invalidpct">Invalid % entry</string> <string name="invalidpct">Invalid % entry</string>
@ -856,7 +836,6 @@
<string name="key_ns_upload" translatable="false">ns_upload</string> <string name="key_ns_upload" translatable="false">ns_upload</string>
<string name="ns_upload_summary">Profiles, boluses, carbs, temporary basals are uploaded to NS</string> <string name="ns_upload_summary">Profiles, boluses, carbs, temporary basals are uploaded to NS</string>
<string name="ns_upload">Upload data to NS</string> <string name="ns_upload">Upload data to NS</string>
<string name="key_ns_receive_profile_store" translatable="false">ns_receive_profile_store</string>
<string name="ns_receive_profile_store">Receive profile store</string> <string name="ns_receive_profile_store">Receive profile store</string>
<string name="ns_receive_profile_store_summary">Synchronize profiles from NS profile editor</string> <string name="ns_receive_profile_store_summary">Synchronize profiles from NS profile editor</string>
<string name="key_ns_receive_temp_target" translatable="false">ns_receive_temp_target</string> <string name="key_ns_receive_temp_target" translatable="false">ns_receive_temp_target</string>
@ -883,15 +862,7 @@
<string name="key_ns_receive_cgm" translatable="false">ns_receive_cgm</string> <string name="key_ns_receive_cgm" translatable="false">ns_receive_cgm</string>
<string name="ns_receive_cgm">Receive/backfill CGM data</string> <string name="ns_receive_cgm">Receive/backfill CGM data</string>
<string name="ns_receive_cgm_summary">Accept CGM data from NS</string> <string name="ns_receive_cgm_summary">Accept CGM data from NS</string>
<string name="missing_profile_name">Missing profile name</string>
<string name="error_in_ic_values">Error in IC values</string>
<string name="error_in_basal_values">Error in basal values</string>
<string name="error_in_target_values">Error in target values</string>
<string name="error_in_isf_values">Error in ISF values</string>
<string name="run_question">Run %s?</string> <string name="run_question">Run %s?</string>
<string name="invalid_profile_not_accepted">Invalid profile %1$s not accepted from NS</string>
<string name="view">View</string>
<string name="errors">Errors</string>
<string name="ns_sync_slow">Slow down uploads</string> <string name="ns_sync_slow">Slow down uploads</string>
<string name="data_status">BG data status</string> <string name="data_status">BG data status</string>
<string name="remove_bg_readings">Remove BG readings</string> <string name="remove_bg_readings">Remove BG readings</string>
@ -917,10 +888,6 @@
<string name="a11y_insulin_label">insulin</string> <string name="a11y_insulin_label">insulin</string>
<string name="a11y_blood_glucose">blood glucose</string> <string name="a11y_blood_glucose">blood glucose</string>
<string name="a11y_bg_outdated">outdated</string> <string name="a11y_bg_outdated">outdated</string>
<string name="a11y_add_new_profile">add new profile</string>
<string name="a11y_clone_profile">clone current profile</string>
<string name="a11y_delete_current_profile">delete current profile</string>
<string name="a11y_add_new_to_list">add new to list</string>
<!-- WEAR OS--> <!-- WEAR OS-->
<string name="wear_action_tempt_preset_error">Temptarget unknown preset: %1$s</string> <string name="wear_action_tempt_preset_error">Temptarget unknown preset: %1$s</string>
<string name="wear_action_tempt_cancel_message">Cancelling running Temp-Targets?</string> <string name="wear_action_tempt_cancel_message">Cancelling running Temp-Targets?</string>
@ -956,7 +923,6 @@
<string name="app_default">Application default</string> <string name="app_default">Application default</string>
<string name="show_invalidated_records">Show invalidated / removed records</string> <string name="show_invalidated_records">Show invalidated / removed records</string>
<string name="hide_invalidated_records">Hide invalidated / removed records</string> <string name="hide_invalidated_records">Hide invalidated / removed records</string>
<string name="select_profile">Select profile to edit</string>
<string name="refresh_from_nightscout">Refresh from Nightscout</string> <string name="refresh_from_nightscout">Refresh from Nightscout</string>
<string name="remove_selected_items">Remove selected items</string> <string name="remove_selected_items">Remove selected items</string>
<string name="select_for_removal">Select for removal</string> <string name="select_for_removal">Select for removal</string>

View file

@ -26,7 +26,7 @@
<SwitchPreference <SwitchPreference
android:defaultValue="true" android:defaultValue="true"
android:key="@string/key_show_wizard_button" android:key="@string/key_show_wizard_button"
android:title="@string/overview_calculator_label" /> android:title="@string/calculator_label" />
<SwitchPreference <SwitchPreference
android:defaultValue="true" android:defaultValue="true"

View file

@ -109,7 +109,6 @@
<string name="please_choose_a_trigger_type">Choose a trigger type</string> <string name="please_choose_a_trigger_type">Choose a trigger type</string>
<string name="please_choose_a_operation_type">Choose a operation type</string> <string name="please_choose_a_operation_type">Choose a operation type</string>
<string name="triggers">Triggers:</string> <string name="triggers">Triggers:</string>
<string name="remove_label">REMOVE</string>
<string name="preconditions">Preconditions:</string> <string name="preconditions">Preconditions:</string>
<string name="automation_event">Automation event</string> <string name="automation_event">Automation event</string>
<string name="reorder_label">Reorder</string> <string name="reorder_label">Reorder</string>

View file

@ -0,0 +1,3 @@
package info.nightscout.androidaps.events
class EventProfileStoreChanged : Event()

View file

@ -14,6 +14,7 @@ interface ActivityNames {
val tddStatsActivity: Class<*> val tddStatsActivity: Class<*>
val errorHelperActivity: Class<*> val errorHelperActivity: Class<*>
val bolusProgressHelperActivity: Class<*> val bolusProgressHelperActivity: Class<*>
val singleFragmentActivity: Class<*>
/** /**
* Show ErrorHelperActivity and start alarm * Show ErrorHelperActivity and start alarm
@ -24,4 +25,5 @@ interface ActivityNames {
*/ */
fun runAlarm(ctx: Context, status: String, title: String, @RawRes soundId: Int = 0) fun runAlarm(ctx: Context, status: String, title: String, @RawRes soundId: Int = 0)
fun runWizard(fragmentManager: FragmentManager, carbs: Int, name: String) fun runWizard(fragmentManager: FragmentManager, carbs: Int, name: String)
fun runProfileSwitchDialog(fragmentManager: FragmentManager, profileName: String?)
} }

View file

@ -7,6 +7,28 @@ interface Overview : ConfigExportImport {
val overviewBus: RxBus val overviewBus: RxBus
/**
* Add notification that shows dialog after clicking button
* @param id if of notification
* @text text of notification
* @level urgency level of notification
* @actionButtonId label of button
* @title Dialog title
* @message Dialog body
*/
fun addNotificationWithDialogResponse(id: Int, text: String, level: Int, @StringRes actionButtonId: Int, title: String, message: String)
/**
* Add notification that executes [Runnable] after clicking button
* @param id if of notification
* @text text of notification
* @level urgency level of notification
* @actionButtonId label of button
* @action Runnable to be run
*/
fun addNotification(id: Int, text: String, level: Int, @StringRes actionButtonId: Int, action: Runnable) fun addNotification(id: Int, text: String, level: Int, @StringRes actionButtonId: Int, action: Runnable)
/**
* Remove notification
* @param id if of notification
*/
fun dismissNotification(id: Int) fun dismissNotification(id: Int)
} }

View file

@ -84,6 +84,8 @@
<string name="key_enable_carbs_required_alert_local" translatable="false">enable_carbs_required_alert_local</string> <string name="key_enable_carbs_required_alert_local" translatable="false">enable_carbs_required_alert_local</string>
<string name="key_smscommunicator_report_pump_unreachable" translatable="false">smscommunicator_report_pump_unreachable</string> <string name="key_smscommunicator_report_pump_unreachable" translatable="false">smscommunicator_report_pump_unreachable</string>
<string name="key_rangetodisplay" translatable="false">rangetodisplay</string> <string name="key_rangetodisplay" translatable="false">rangetodisplay</string>
<string name="key_local_profile_last_change" translatable="false">local_profile_last_change</string>
<string name="key_ns_receive_profile_store" translatable="false">ns_receive_profile_store</string>
<!-- General--> <!-- General-->
<string name="refresh">Refresh</string> <string name="refresh">Refresh</string>
@ -228,6 +230,9 @@
<string name="tir">TIR</string> <string name="tir">TIR</string>
<string name="tdd_total">TDD Total</string> <string name="tdd_total">TDD Total</string>
<string name="none"><![CDATA[<none>]]></string> <string name="none"><![CDATA[<none>]]></string>
<string name="remove_label">REMOVE</string>
<string name="activate_profile">Activate profile</string>
<string name="reset">reset</string>
<!-- Constraints--> <!-- Constraints-->
<string name="limitingbasalratio">Limiting max basal rate to %1$.2f U/h because of %2$s</string> <string name="limitingbasalratio">Limiting max basal rate to %1$.2f U/h because of %2$s</string>

View file

@ -1,4 +1,4 @@
package info.nightscout.androidaps.plugins.profile.local package info.nightscout.plugins.profile
import android.os.Bundle import android.os.Bundle
import android.text.Editable import android.text.Editable
@ -11,31 +11,29 @@ import android.widget.ArrayAdapter
import com.google.android.material.tabs.TabLayout import com.google.android.material.tabs.TabLayout
import dagger.android.support.DaggerFragment import dagger.android.support.DaggerFragment
import info.nightscout.androidaps.Constants import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.R
import info.nightscout.androidaps.activities.SingleFragmentActivity
import info.nightscout.androidaps.data.ProfileSealed import info.nightscout.androidaps.data.ProfileSealed
import info.nightscout.androidaps.database.entities.UserEntry.Action import info.nightscout.androidaps.database.entities.UserEntry
import info.nightscout.androidaps.database.entities.UserEntry.Sources
import info.nightscout.androidaps.database.entities.ValueWithUnit import info.nightscout.androidaps.database.entities.ValueWithUnit
import info.nightscout.androidaps.databinding.LocalprofileFragmentBinding
import info.nightscout.androidaps.dialogs.ProfileSwitchDialog
import info.nightscout.androidaps.extensions.toVisibility import info.nightscout.androidaps.extensions.toVisibility
import info.nightscout.androidaps.interfaces.ActivePlugin import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.interfaces.ActivityNames
import info.nightscout.androidaps.interfaces.GlucoseUnit import info.nightscout.androidaps.interfaces.GlucoseUnit
import info.nightscout.androidaps.interfaces.Profile import info.nightscout.androidaps.interfaces.Profile
import info.nightscout.androidaps.interfaces.ProfileFunction import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.interfaces.ResourceHelper
import info.nightscout.androidaps.logging.UserEntryLogger import info.nightscout.androidaps.logging.UserEntryLogger
import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.plugins.profile.local.events.EventLocalProfileChanged
import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.DecimalFormatter import info.nightscout.androidaps.utils.DecimalFormatter
import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.HardLimits import info.nightscout.androidaps.utils.HardLimits
import info.nightscout.androidaps.utils.alertDialogs.OKDialog import info.nightscout.androidaps.utils.alertDialogs.OKDialog
import info.nightscout.androidaps.utils.protection.ProtectionCheck import info.nightscout.androidaps.utils.protection.ProtectionCheck
import info.nightscout.androidaps.interfaces.ResourceHelper
import info.nightscout.androidaps.utils.rx.AapsSchedulers import info.nightscout.androidaps.utils.rx.AapsSchedulers
import info.nightscout.androidaps.utils.ui.TimeListEdit import info.nightscout.plugins.R
import info.nightscout.plugins.databinding.ProfileFragmentBinding
import info.nightscout.plugins.profile.events.EventLocalProfileChanged
import info.nightscout.plugins.ui.TimeListEdit
import info.nightscout.shared.SafeParse import info.nightscout.shared.SafeParse
import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.AAPSLogger
import info.nightscout.shared.logging.LTag import info.nightscout.shared.logging.LTag
@ -45,20 +43,21 @@ import java.math.RoundingMode
import java.text.DecimalFormat import java.text.DecimalFormat
import javax.inject.Inject import javax.inject.Inject
class LocalProfileFragment : DaggerFragment() { class ProfileFragment : DaggerFragment() {
@Inject lateinit var aapsLogger: AAPSLogger @Inject lateinit var aapsLogger: AAPSLogger
@Inject lateinit var rxBus: RxBus @Inject lateinit var rxBus: RxBus
@Inject lateinit var rh: ResourceHelper @Inject lateinit var rh: ResourceHelper
@Inject lateinit var activePlugin: ActivePlugin @Inject lateinit var activePlugin: ActivePlugin
@Inject lateinit var fabricPrivacy: FabricPrivacy @Inject lateinit var fabricPrivacy: FabricPrivacy
@Inject lateinit var localProfilePlugin: LocalProfilePlugin @Inject lateinit var profilePlugin: ProfilePlugin
@Inject lateinit var profileFunction: ProfileFunction @Inject lateinit var profileFunction: ProfileFunction
@Inject lateinit var hardLimits: HardLimits @Inject lateinit var hardLimits: HardLimits
@Inject lateinit var protectionCheck: ProtectionCheck @Inject lateinit var protectionCheck: ProtectionCheck
@Inject lateinit var dateUtil: DateUtil @Inject lateinit var dateUtil: DateUtil
@Inject lateinit var aapsSchedulers: AapsSchedulers @Inject lateinit var aapsSchedulers: AapsSchedulers
@Inject lateinit var uel: UserEntryLogger @Inject lateinit var uel: UserEntryLogger
@Inject lateinit var activityNames: ActivityNames
private var disposable: CompositeDisposable = CompositeDisposable() private var disposable: CompositeDisposable = CompositeDisposable()
private var inMenu = false private var inMenu = false
@ -68,7 +67,7 @@ class LocalProfileFragment : DaggerFragment() {
private val save = Runnable { private val save = Runnable {
doEdit() doEdit()
basalView?.updateLabel(rh.gs(R.string.basal_label) + ": " + sumLabel()) basalView?.updateLabel(rh.gs(R.string.basal_label) + ": " + sumLabel())
localProfilePlugin.getEditedProfile()?.let { profilePlugin.getEditedProfile()?.let {
binding.basalGraph.show(ProfileSealed.Pure(it)) binding.basalGraph.show(ProfileSealed.Pure(it))
binding.icGraph.show(ProfileSealed.Pure(it)) binding.icGraph.show(ProfileSealed.Pure(it))
binding.isfGraph.show(ProfileSealed.Pure(it)) binding.isfGraph.show(ProfileSealed.Pure(it))
@ -81,32 +80,32 @@ class LocalProfileFragment : DaggerFragment() {
override fun afterTextChanged(s: Editable) {} override fun afterTextChanged(s: Editable) {}
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {} override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) { override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
localProfilePlugin.currentProfile()?.dia = SafeParse.stringToDouble(binding.dia.text) profilePlugin.currentProfile()?.dia = SafeParse.stringToDouble(binding.dia.text)
localProfilePlugin.currentProfile()?.name = binding.name.text.toString() profilePlugin.currentProfile()?.name = binding.name.text.toString()
doEdit() doEdit()
} }
} }
private fun sumLabel(): String { private fun sumLabel(): String {
val profile = localProfilePlugin.getEditedProfile() val profile = profilePlugin.getEditedProfile()
val sum = profile?.let { ProfileSealed.Pure(profile).baseBasalSum() } ?: 0.0 val sum = profile?.let { ProfileSealed.Pure(profile).baseBasalSum() } ?: 0.0
return "" + DecimalFormatter.to2Decimal(sum) + rh.gs(R.string.insulin_unit_shortname) return "" + DecimalFormatter.to2Decimal(sum) + rh.gs(R.string.insulin_unit_shortname)
} }
private var _binding: LocalprofileFragmentBinding? = null private var _binding: ProfileFragmentBinding? = 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 val binding get() = _binding!!
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
_binding = LocalprofileFragmentBinding.inflate(inflater, container, false) _binding = ProfileFragmentBinding.inflate(inflater, container, false)
return binding.root return binding.root
} }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
val parentClass = this.activity?.let { it::class.java } val parentClass = this.activity?.let { it::class.java }
inMenu = parentClass == SingleFragmentActivity::class.java inMenu = parentClass == activityNames.singleFragmentActivity
updateProtectedUi() updateProtectedUi()
processVisibility(0) processVisibility(0)
binding.tabLayout.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener { binding.tabLayout.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
@ -120,16 +119,16 @@ class LocalProfileFragment : DaggerFragment() {
binding.diaLabel.labelFor = binding.dia.editTextId binding.diaLabel.labelFor = binding.dia.editTextId
binding.unlock.setOnClickListener { queryProtection() } binding.unlock.setOnClickListener { queryProtection() }
val profiles = localProfilePlugin.profile?.getProfileList() ?: ArrayList() val profiles = profilePlugin.profile?.getProfileList() ?: ArrayList()
val activeProfile = profileFunction.getProfileName() val activeProfile = profileFunction.getProfileName()
val profileIndex = profiles.indexOf(activeProfile) val profileIndex = profiles.indexOf(activeProfile)
localProfilePlugin.currentProfileIndex = if (profileIndex >= 0) profileIndex else 0 profilePlugin.currentProfileIndex = if (profileIndex >= 0) profileIndex else 0
} }
fun build() { fun build() {
val pumpDescription = activePlugin.activePump.pumpDescription val pumpDescription = activePlugin.activePump.pumpDescription
if (localProfilePlugin.numOfProfiles == 0) localProfilePlugin.addNewProfile() if (profilePlugin.numOfProfiles == 0) profilePlugin.addNewProfile()
val currentProfile = localProfilePlugin.currentProfile() ?: return val currentProfile = profilePlugin.currentProfile() ?: return
val units = if (currentProfile.mgdl) Constants.MGDL else Constants.MMOL val units = if (currentProfile.mgdl) Constants.MGDL else Constants.MMOL
binding.name.removeTextChangedListener(textWatch) binding.name.removeTextChangedListener(textWatch)
@ -223,28 +222,28 @@ class LocalProfileFragment : DaggerFragment() {
} }
context?.let { context -> context?.let { context ->
val profileList: ArrayList<CharSequence> = localProfilePlugin.profile?.getProfileList() ?: ArrayList() val profileList: ArrayList<CharSequence> = profilePlugin.profile?.getProfileList() ?: ArrayList()
binding.profileList.setAdapter(ArrayAdapter(context, R.layout.spinner_centered, profileList)) binding.profileList.setAdapter(ArrayAdapter(context, R.layout.spinner_centered, profileList))
} ?: return } ?: return
binding.profileList.onItemClickListener = AdapterView.OnItemClickListener { _, _, position, _ -> binding.profileList.onItemClickListener = AdapterView.OnItemClickListener { _, _, position, _ ->
if (localProfilePlugin.isEdited) { if (profilePlugin.isEdited) {
activity?.let { activity -> activity?.let { activity ->
OKDialog.showConfirmation( OKDialog.showConfirmation(
activity, rh.gs(R.string.doyouwantswitchprofile), activity, rh.gs(R.string.do_you_want_switch_profile),
{ {
localProfilePlugin.currentProfileIndex = position profilePlugin.currentProfileIndex = position
localProfilePlugin.isEdited = false profilePlugin.isEdited = false
build() build()
}, null }, null
) )
} }
} else { } else {
localProfilePlugin.currentProfileIndex = position profilePlugin.currentProfileIndex = position
build() build()
} }
} }
localProfilePlugin.getEditedProfile()?.let { profilePlugin.getEditedProfile()?.let {
binding.basalGraph.show(ProfileSealed.Pure(it)) binding.basalGraph.show(ProfileSealed.Pure(it))
binding.icGraph.show(ProfileSealed.Pure(it)) binding.icGraph.show(ProfileSealed.Pure(it))
binding.isfGraph.show(ProfileSealed.Pure(it)) binding.isfGraph.show(ProfileSealed.Pure(it))
@ -253,40 +252,40 @@ class LocalProfileFragment : DaggerFragment() {
} }
binding.profileAdd.setOnClickListener { binding.profileAdd.setOnClickListener {
if (localProfilePlugin.isEdited) { if (profilePlugin.isEdited) {
activity?.let { OKDialog.show(it, "", rh.gs(R.string.saveorresetchangesfirst)) } activity?.let { OKDialog.show(it, "", rh.gs(R.string.save_or_reset_changes_first)) }
} else { } else {
uel.log(Action.NEW_PROFILE, Sources.LocalProfile) uel.log(UserEntry.Action.NEW_PROFILE, UserEntry.Sources.LocalProfile)
localProfilePlugin.addNewProfile() profilePlugin.addNewProfile()
build() build()
} }
} }
binding.profileClone.setOnClickListener { binding.profileClone.setOnClickListener {
if (localProfilePlugin.isEdited) { if (profilePlugin.isEdited) {
activity?.let { OKDialog.show(it, "", rh.gs(R.string.saveorresetchangesfirst)) } activity?.let { OKDialog.show(it, "", rh.gs(R.string.save_or_reset_changes_first)) }
} else { } else {
uel.log( uel.log(
Action.CLONE_PROFILE, Sources.LocalProfile, ValueWithUnit.SimpleString( UserEntry.Action.CLONE_PROFILE, UserEntry.Sources.LocalProfile, ValueWithUnit.SimpleString(
localProfilePlugin.currentProfile()?.name profilePlugin.currentProfile()?.name
?: "" ?: ""
) )
) )
localProfilePlugin.cloneProfile() profilePlugin.cloneProfile()
build() build()
} }
} }
binding.profileRemove.setOnClickListener { binding.profileRemove.setOnClickListener {
activity?.let { activity -> activity?.let { activity ->
OKDialog.showConfirmation(activity, rh.gs(R.string.deletecurrentprofile), { OKDialog.showConfirmation(activity, rh.gs(R.string.delete_current_profile), {
uel.log( uel.log(
Action.PROFILE_REMOVED, Sources.LocalProfile, ValueWithUnit.SimpleString( UserEntry.Action.PROFILE_REMOVED, UserEntry.Sources.LocalProfile, ValueWithUnit.SimpleString(
localProfilePlugin.currentProfile()?.name profilePlugin.currentProfile()?.name
?: "" ?: ""
) )
) )
localProfilePlugin.removeCurrentProfile() profilePlugin.removeCurrentProfile()
build() build()
}, null) }, null)
} }
@ -299,27 +298,25 @@ class LocalProfileFragment : DaggerFragment() {
binding.units.text = rh.gs(R.string.units_colon) + " " + (if (currentProfile.mgdl) rh.gs(R.string.mgdl) else rh.gs(R.string.mmol)) binding.units.text = rh.gs(R.string.units_colon) + " " + (if (currentProfile.mgdl) rh.gs(R.string.mgdl) else rh.gs(R.string.mmol))
binding.profileswitch.setOnClickListener { binding.profileswitch.setOnClickListener {
ProfileSwitchDialog() activityNames.runProfileSwitchDialog(childFragmentManager, profilePlugin.currentProfile()?.name)
.also { it.arguments = Bundle().also { bundle -> bundle.putString("profileName", localProfilePlugin.currentProfile()?.name) } }
.show(childFragmentManager, "ProfileSwitchDialog")
} }
binding.reset.setOnClickListener { binding.reset.setOnClickListener {
localProfilePlugin.loadSettings() profilePlugin.loadSettings()
build() build()
} }
binding.save.setOnClickListener { binding.save.setOnClickListener {
if (!localProfilePlugin.isValidEditState(activity)) { if (!profilePlugin.isValidEditState(activity)) {
return@setOnClickListener //Should not happen as saveButton should not be visible if not valid return@setOnClickListener //Should not happen as saveButton should not be visible if not valid
} }
uel.log( uel.log(
Action.STORE_PROFILE, Sources.LocalProfile, ValueWithUnit.SimpleString( UserEntry.Action.STORE_PROFILE, UserEntry.Sources.LocalProfile, ValueWithUnit.SimpleString(
localProfilePlugin.currentProfile()?.name profilePlugin.currentProfile()?.name
?: "" ?: ""
) )
) )
localProfilePlugin.storeSettings(activity) profilePlugin.storeSettings(activity)
build() build()
} }
updateGUI() updateGUI()
@ -349,7 +346,7 @@ class LocalProfileFragment : DaggerFragment() {
} }
fun doEdit() { fun doEdit() {
localProfilePlugin.isEdited = true profilePlugin.isEdited = true
updateGUI() updateGUI()
} }
@ -363,8 +360,8 @@ class LocalProfileFragment : DaggerFragment() {
private fun updateGUI() { private fun updateGUI() {
if (_binding == null) return if (_binding == null) return
val isValid = localProfilePlugin.isValidEditState(activity) val isValid = profilePlugin.isValidEditState(activity)
val isEdited = localProfilePlugin.isEdited val isEdited = profilePlugin.isEdited
if (isValid) { if (isValid) {
this.view?.setBackgroundColor(rh.gac(context, R.attr.okBackgroundColor)) this.view?.setBackgroundColor(rh.gac(context, R.attr.okBackgroundColor))
binding.profileList.isEnabled = true binding.profileList.isEnabled = true

View file

@ -1,4 +1,4 @@
package info.nightscout.androidaps.plugins.profile.local package info.nightscout.plugins.profile
import android.content.Context import android.content.Context
import androidx.fragment.app.FragmentActivity import androidx.fragment.app.FragmentActivity
@ -7,38 +7,48 @@ import androidx.work.WorkerParameters
import androidx.work.workDataOf import androidx.work.workDataOf
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.Constants import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.R
import info.nightscout.androidaps.annotations.OpenForTesting import info.nightscout.androidaps.annotations.OpenForTesting
import info.nightscout.androidaps.data.ProfileSealed import info.nightscout.androidaps.data.ProfileSealed
import info.nightscout.androidaps.data.PureProfile import info.nightscout.androidaps.data.PureProfile
import info.nightscout.androidaps.events.EventProfileStoreChanged import info.nightscout.androidaps.events.EventProfileStoreChanged
import info.nightscout.androidaps.extensions.blockFromJsonArray import info.nightscout.androidaps.extensions.blockFromJsonArray
import info.nightscout.androidaps.extensions.pureProfileFromJson import info.nightscout.androidaps.extensions.pureProfileFromJson
import info.nightscout.androidaps.interfaces.* import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.interfaces.Config
import info.nightscout.androidaps.interfaces.GlucoseUnit
import info.nightscout.androidaps.interfaces.PluginBase
import info.nightscout.androidaps.interfaces.PluginDescription
import info.nightscout.androidaps.interfaces.PluginType
import info.nightscout.androidaps.interfaces.Profile
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.interfaces.ProfileSource
import info.nightscout.androidaps.interfaces.ProfileStore
import info.nightscout.androidaps.interfaces.ResourceHelper
import info.nightscout.androidaps.interfaces.XDripBroadcast
import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification
import info.nightscout.androidaps.receivers.DataWorkerStorage
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.DecimalFormatter
import info.nightscout.androidaps.utils.HardLimits
import info.nightscout.androidaps.utils.JsonHelper
import info.nightscout.androidaps.utils.ToastUtils
import info.nightscout.androidaps.utils.alertDialogs.OKDialog
import info.nightscout.plugins.R
import info.nightscout.plugins.profile.events.EventLocalProfileChanged
import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.AAPSLogger
import info.nightscout.shared.logging.LTag import info.nightscout.shared.logging.LTag
import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification
import info.nightscout.androidaps.plugins.general.overview.notifications.NotificationWithAction
import info.nightscout.androidaps.plugins.profile.local.events.EventLocalProfileChanged
import info.nightscout.androidaps.receivers.DataWorkerStorage
import info.nightscout.androidaps.utils.*
import info.nightscout.androidaps.utils.alertDialogs.OKDialog
import info.nightscout.androidaps.interfaces.ResourceHelper
import info.nightscout.shared.sharedPreferences.SP import info.nightscout.shared.sharedPreferences.SP
import org.json.JSONArray import org.json.JSONArray
import org.json.JSONException import org.json.JSONException
import org.json.JSONObject import org.json.JSONObject
import java.lang.Integer.min import java.util.TimeZone
import java.util.*
import javax.inject.Inject import javax.inject.Inject
import javax.inject.Singleton import javax.inject.Singleton
import kotlin.collections.ArrayList
@OpenForTesting @OpenForTesting
@Singleton @Singleton
class LocalProfilePlugin @Inject constructor( class ProfilePlugin @Inject constructor(
injector: HasAndroidInjector, injector: HasAndroidInjector,
aapsLogger: AAPSLogger, aapsLogger: AAPSLogger,
private val rxBus: RxBus, private val rxBus: RxBus,
@ -49,9 +59,10 @@ class LocalProfilePlugin @Inject constructor(
private val hardLimits: HardLimits, private val hardLimits: HardLimits,
private val dateUtil: DateUtil, private val dateUtil: DateUtil,
private val config: Config private val config: Config
) : PluginBase(PluginDescription() ) : PluginBase(
PluginDescription()
.mainType(PluginType.PROFILE) .mainType(PluginType.PROFILE)
.fragmentClass(LocalProfileFragment::class.java.name) .fragmentClass(ProfileFragment::class.java.name)
.enableByDefault(true) .enableByDefault(true)
.pluginIcon(R.drawable.ic_local_profile) .pluginIcon(R.drawable.ic_local_profile)
.pluginName(R.string.localprofile) .pluginName(R.string.localprofile)
@ -74,10 +85,10 @@ class LocalProfilePlugin @Inject constructor(
internal var name: String? = null internal var name: String? = null
internal var mgdl: Boolean = false internal var mgdl: Boolean = false
internal var dia: Double = Constants.defaultDIA var dia: Double = Constants.defaultDIA
internal var ic: JSONArray? = null var ic: JSONArray? = null
internal var isf: JSONArray? = null var isf: JSONArray? = null
internal var basal: JSONArray? = null var basal: JSONArray? = null
internal var targetLow: JSONArray? = null internal var targetLow: JSONArray? = null
internal var targetHigh: JSONArray? = null internal var targetHigh: JSONArray? = null
@ -100,7 +111,7 @@ class LocalProfilePlugin @Inject constructor(
var profiles: ArrayList<SingleProfile> = ArrayList() var profiles: ArrayList<SingleProfile> = ArrayList()
val numOfProfiles get() = profiles.size val numOfProfiles get() = profiles.size
internal var currentProfileIndex = 0 var currentProfileIndex = 0
fun currentProfile(): SingleProfile? = if (numOfProfiles > 0 && currentProfileIndex < numOfProfiles) profiles[currentProfileIndex] else null fun currentProfile(): SingleProfile? = if (numOfProfiles > 0 && currentProfileIndex < numOfProfiles) profiles[currentProfileIndex] else null
@ -109,7 +120,7 @@ class LocalProfilePlugin @Inject constructor(
val pumpDescription = activePlugin.activePump.pumpDescription val pumpDescription = activePlugin.activePump.pumpDescription
with(profiles[currentProfileIndex]) { with(profiles[currentProfileIndex]) {
if (dia < hardLimits.minDia() || dia > hardLimits.maxDia()) { if (dia < hardLimits.minDia() || dia > hardLimits.maxDia()) {
ToastUtils.errorToast(activity, rh.gs(R.string.value_out_of_hard_limits, rh.gs(info.nightscout.androidaps.core.R.string.profile_dia), dia)) ToastUtils.errorToast(activity, rh.gs(R.string.value_out_of_hard_limits, rh.gs(R.string.profile_dia), dia))
return false return false
} }
if (name.isNullOrEmpty()) { if (name.isNullOrEmpty()) {
@ -216,7 +227,7 @@ class LocalProfilePlugin @Inject constructor(
if (name.contains(".")) namesOK = false if (name.contains(".")) namesOK = false
} }
if (!namesOK) activity?.let { if (!namesOK) activity?.let {
OKDialog.show(it, "", rh.gs(R.string.profilenamecontainsdot)) OKDialog.show(it, "", rh.gs(R.string.profile_name_contains_dot))
} }
} }
@ -261,18 +272,14 @@ class LocalProfilePlugin @Inject constructor(
sp.name = p.toString() sp.name = p.toString()
newProfiles.add(sp) newProfiles.add(sp)
} else { } else {
val n = NotificationWithAction( activePlugin.activeOverview.addNotificationWithDialogResponse(
injector,
Notification.INVALID_PROFILE_NOT_ACCEPTED, Notification.INVALID_PROFILE_NOT_ACCEPTED,
rh.gs(R.string.invalid_profile_not_accepted, p.toString()), rh.gs(R.string.invalid_profile_not_accepted, p.toString()),
Notification.NORMAL Notification.NORMAL,
R.string.view,
rh.gs(R.string.errors),
validityCheck.reasons.joinToString(separator = "\n")
) )
n.action(R.string.view) {
n.contextForAction?.let {
OKDialog.show(it, rh.gs(R.string.errors), validityCheck.reasons.joinToString(separator = "\n"), null)
}
}
rxBus.send(EventNewNotification(n))
} }
} }
if (newProfiles.size > 0) { if (newProfiles.size > 0) {
@ -460,7 +467,7 @@ class LocalProfilePlugin @Inject constructor(
@Inject lateinit var dataWorkerStorage: DataWorkerStorage @Inject lateinit var dataWorkerStorage: DataWorkerStorage
@Inject lateinit var sp: SP @Inject lateinit var sp: SP
@Inject lateinit var config: Config @Inject lateinit var config: Config
@Inject lateinit var localProfilePlugin: LocalProfilePlugin @Inject lateinit var profilePlugin: ProfilePlugin
@Inject lateinit var xDripBroadcast: XDripBroadcast @Inject lateinit var xDripBroadcast: XDripBroadcast
init { init {
@ -478,9 +485,9 @@ class LocalProfilePlugin @Inject constructor(
aapsLogger.debug(LTag.PROFILE, "Received profileStore: createdAt: $createdAt Local last modification: $lastLocalChange") aapsLogger.debug(LTag.PROFILE, "Received profileStore: createdAt: $createdAt Local last modification: $lastLocalChange")
@Suppress("LiftReturnOrAssignment") @Suppress("LiftReturnOrAssignment")
if (createdAt > lastLocalChange || createdAt % 1000 == 0L) {// whole second means edited in NS if (createdAt > lastLocalChange || createdAt % 1000 == 0L) {// whole second means edited in NS
localProfilePlugin.loadFromStore(store) profilePlugin.loadFromStore(store)
aapsLogger.debug(LTag.PROFILE, "Received profileStore: $profileJson") aapsLogger.debug(LTag.PROFILE, "Received profileStore: $profileJson")
return Result.success(workDataOf("Data" to profileJson.toString().substring(0..min(5000, profileJson.length())))) return Result.success(workDataOf("Data" to profileJson.toString().substring(0..Integer.min(5000, profileJson.length()))))
} else } else
return Result.success(workDataOf("Result" to "Unchanged. Ignoring")) return Result.success(workDataOf("Result" to "Unchanged. Ignoring"))
} }

View file

@ -1,4 +1,4 @@
package info.nightscout.androidaps.plugins.profile.local.events package info.nightscout.plugins.profile.events
import info.nightscout.androidaps.events.Event import info.nightscout.androidaps.events.Event

View file

@ -0,0 +1,146 @@
package info.nightscout.plugins.ui
import android.view.MotionEvent
import android.view.View
import android.widget.AdapterView
import android.widget.Spinner
import android.widget.SpinnerAdapter
import kotlin.math.max
/**
* Spinner Helper class that works around some common issues
* with the stock Android Spinner
*
* A Spinner will normally call it's OnItemSelectedListener
* when you use setSelection(...) in your initialization code.
* This is usually unwanted behavior, and a common work-around
* is to use spinner.post(...) with a Runnable to assign the
* OnItemSelectedListener after layout.
*
* If you do not call setSelection(...) manually, the callback
* may be called with the first item in the adapter you have
* set. The common work-around for that is to count callbacks.
*
* While these workarounds usually *seem* to work, the callback
* may still be called repeatedly for other reasons while the
* selection hasn't actually changed. This will happen for
* example, if the user has accessibility options enabled -
* which is more common than you might think as several apps
* use this for different purposes, like detecting which
* notifications are active.
*
* Ideally, your OnItemSelectedListener callback should be
* coded defensively so that no problem would occur even
* if the callback was called repeatedly with the same values
* without any user interaction, so no workarounds are needed.
*
* This class does that for you. It keeps track of the values
* you have set with the setSelection(...) methods, and
* proxies the OnItemSelectedListener callback so your callback
* only gets called if the selected item's position differs
* from the one you have set by code, or the first item if you
* did not set it.
*
* This also means that if the user actually clicks the item
* that was previously selected by code (or the first item
* if you didn't set a selection by code), the callback will
* not fire.
*
* To implement, replace current occurrences of:
*
* Spinner spinner =
* (Spinner)findViewById(R.id.xxx);
*
* with:
*
* SpinnerHelper spinner =
* new SpinnerHelper(findViewById(R.id.xxx))
*
* SpinnerHelper proxies the (my) most used calls to Spinner
* but not all of them. Should a method not be available, use:
*
* spinner.getSpinner().someMethod(...)
*
* Or just add the proxy method yourself :)
*
* (Quickly) Tested on devices from 2.3.6 through 4.2.2
*
* @author Jorrit "Chainfire" Jongma
* @license WTFPL (do whatever you want with this, nobody cares)
*/
@Suppress("unused")
class SpinnerHelper(val spinner: Spinner) : AdapterView.OnItemSelectedListener {
private var userTouched = false
private var lastPosition = -1
private var proxiedItemSelectedListener: AdapterView.OnItemSelectedListener? = null
fun setSelection(position: Int) {
lastPosition = max(-1, position)
spinner.setSelection(position)
}
fun setSelection(position: Int, animate: Boolean) {
lastPosition = max(-1, position)
spinner.setSelection(position, animate)
}
fun setOnItemSelectedListener(listener: AdapterView.OnItemSelectedListener?) {
proxiedItemSelectedListener = listener
setTouchListener()
spinner.onItemSelectedListener = if (listener == null) null else this
}
private fun setTouchListener() {
spinner.setOnTouchListener { v: View, _: MotionEvent? ->
v.performClick()
userTouched = true
false
}
}
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
if (position != lastPosition && userTouched) {
lastPosition = position
proxiedItemSelectedListener?.onItemSelected(parent, view, position, id)
}
}
override fun onNothingSelected(parent: AdapterView<*>?) {
if (lastPosition != -1) {
lastPosition = -1
proxiedItemSelectedListener?.onNothingSelected(parent)
}
}
var adapter: SpinnerAdapter
get() = spinner.adapter
set(adapter) {
if (adapter.count > 0) {
lastPosition = 0
}
spinner.adapter = adapter
}
val count: Int
get() = spinner.count
fun getItemAtPosition(position: Int): Any = spinner.getItemAtPosition(position)
fun getItemIdAtPosition(position: Int): Long = spinner.getItemIdAtPosition(position)
val selectedItem: Any
get() = try {
spinner.selectedItem
} catch (e: IndexOutOfBoundsException) {
adapter.getItem(adapter.count - 1)
}
val selectedItemId: Long
get() = spinner.selectedItemId
val selectedItemPosition: Int
get() = spinner.selectedItemPosition
var isEnabled: Boolean
get() = spinner.isEnabled
set(enabled) {
spinner.isEnabled = enabled
}
}

View file

@ -1,4 +1,4 @@
package info.nightscout.androidaps.utils.ui; package info.nightscout.plugins.ui;
import android.content.Context; import android.content.Context;
import android.text.Editable; import android.text.Editable;
@ -24,10 +24,11 @@ import java.text.NumberFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import info.nightscout.androidaps.R;
import info.nightscout.shared.logging.AAPSLogger;
import info.nightscout.androidaps.utils.DateUtil; import info.nightscout.androidaps.utils.DateUtil;
import info.nightscout.androidaps.utils.ui.NumberPicker;
import info.nightscout.plugins.R;
import info.nightscout.shared.SafeParse; import info.nightscout.shared.SafeParse;
import info.nightscout.shared.logging.AAPSLogger;
/** /**
* Created by mike on 29.12.2016. * Created by mike on 29.12.2016.

View file

@ -89,7 +89,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_gravity="center" android:layout_gravity="center"
android:contentDescription="@string/overview_calculator_label" android:contentDescription="@string/calculator_label"
android:orientation="horizontal" android:orientation="horizontal"
android:paddingStart="-5dp" android:paddingStart="-5dp"
android:paddingEnd="-5dp" android:paddingEnd="-5dp"

View file

@ -3,7 +3,7 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context=".plugins.profile.local.LocalProfileFragment"> tools:context="info.nightscout.plugins.profile.ProfileFragment">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"

View file

@ -157,9 +157,12 @@
<string name="shortenergy">En</string> <string name="shortenergy">En</string>
<string name="shortprotein">Pr</string> <string name="shortprotein">Pr</string>
<string name="shortfat">Fat</string> <string name="shortfat">Fat</string>
<string name="theme_switcher">Theme switcher</string> <string name="category">Category</string>
<string name="subcategory">Subcategory</string>
<string name="calculator_label">Calculator</string>
<!-- Theme switcher dark and light mode--> <!-- Theme switcher dark and light mode-->
<string name="theme_switcher">Theme switcher</string>
<string name="theme_switcher_summary">Choose dark, light, or to follow the system theme</string> <string name="theme_switcher_summary">Choose dark, light, or to follow the system theme</string>
<string name="app_color_scheme">App Color Scheme</string> <string name="app_color_scheme">App Color Scheme</string>
<string name="dark_theme">Dark theme</string> <string name="dark_theme">Dark theme</string>
@ -169,4 +172,34 @@
<string name="value_light_theme" translatable="false">light</string> <string name="value_light_theme" translatable="false">light</string>
<string name="value_system_theme" translatable="false">system</string> <string name="value_system_theme" translatable="false">system</string>
<!-- Profile -->
<string name="localprofile">Profile</string>
<string name="localprofile_shortname">LP</string>
<string name="description_profile_local">Define a profile which is available offline.</string>
<string name="a11y_add_new_to_list">add new to list</string>
<string name="do_you_want_switch_profile">Do you want to switch profile and discard changes made to current profile?</string>
<string name="save_or_reset_changes_first">Save or reset current changes first</string>
<string name="delete_current_profile">Delete current profile?</string>
<string name="units_colon">Units:</string>
<string name="missing_profile_name">Missing profile name</string>
<string name="error_in_ic_values">Error in IC values</string>
<string name="error_in_basal_values">Error in basal values</string>
<string name="error_in_target_values">Error in target values</string>
<string name="error_in_isf_values">Error in ISF values</string>
<string name="profile_name_contains_dot">Profile name contains dots.\nThis is not supported by NS.\nProfile is not uploaded to NS.</string>
<string name="invalid_profile_not_accepted">Invalid profile %1$s not accepted from NS</string>
<string name="view">View</string>
<string name="errors">Errors</string>
<string name="select_profile">Select profile to edit</string>
<string name="profile_name">Profile name:</string>
<string name="a11y_add_new_profile">add new profile</string>
<string name="a11y_clone_profile">clone current profile</string>
<string name="a11y_delete_current_profile">delete current profile</string>
<string name="dia_short">DIA</string>
<string name="ic_short">IC</string>
<string name="isf_short">ISF</string>
<string name="target_short">TARG</string>
<string name="clone_label">Clone</string>
<string name="basal_short">BAS</string>
</resources> </resources>

View file

@ -26,7 +26,6 @@
<string name="calculation_in_progress">Calculation in progress</string> <string name="calculation_in_progress">Calculation in progress</string>
<string name="invalid_age">Invalid age entry</string> <string name="invalid_age">Invalid age entry</string>
<string name="invalid_weight">Invalid weight entry</string> <string name="invalid_weight">Invalid weight entry</string>
<string name="reset">reset</string>
<string name="id">ID:</string> <string name="id">ID:</string>
<string name="submit">Submit</string> <string name="submit">Submit</string>
<string name="profile">Profile</string> <string name="profile">Profile</string>