package info.nightscout.androidaps.activities import android.content.Context import android.content.SharedPreferences import android.content.SharedPreferences.OnSharedPreferenceChangeListener import android.os.Bundle import androidx.annotation.XmlRes import androidx.preference.* import dagger.android.AndroidInjector import dagger.android.DispatchingAndroidInjector import dagger.android.HasAndroidInjector import dagger.android.support.AndroidSupportInjection import info.nightscout.androidaps.Config import info.nightscout.androidaps.R import info.nightscout.androidaps.data.Profile import info.nightscout.androidaps.events.EventPreferenceChange import info.nightscout.androidaps.events.EventRebuildTabs import info.nightscout.androidaps.interfaces.PluginBase import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin import info.nightscout.androidaps.plugins.aps.openAPSAMA.OpenAPSAMAPlugin import info.nightscout.androidaps.plugins.aps.openAPSMA.OpenAPSMAPlugin import info.nightscout.androidaps.plugins.aps.openAPSSMB.OpenAPSSMBPlugin import info.nightscout.androidaps.plugins.bus.RxBusWrapper import info.nightscout.androidaps.plugins.configBuilder.PluginStore import info.nightscout.androidaps.plugins.configBuilder.ProfileFunction import info.nightscout.androidaps.plugins.constraints.safety.SafetyPlugin import info.nightscout.androidaps.plugins.general.automation.AutomationPlugin import info.nightscout.androidaps.plugins.general.careportal.CareportalPlugin import info.nightscout.androidaps.plugins.general.maintenance.MaintenancePlugin import info.nightscout.androidaps.plugins.general.nsclient.NSClientPlugin import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin import info.nightscout.androidaps.plugins.general.tidepool.TidepoolPlugin import info.nightscout.androidaps.plugins.general.wear.WearPlugin import info.nightscout.androidaps.plugins.general.xdripStatusline.StatusLinePlugin import info.nightscout.androidaps.plugins.insulin.InsulinOrefFreePeakPlugin import info.nightscout.androidaps.plugins.pump.combo.ComboPlugin import info.nightscout.androidaps.plugins.pump.danaR.DanaRPlugin import info.nightscout.androidaps.plugins.pump.danaRKorean.DanaRKoreanPlugin import info.nightscout.androidaps.plugins.pump.danaRS.DanaRSPlugin import info.nightscout.androidaps.plugins.pump.danaRv2.DanaRv2Plugin import info.nightscout.androidaps.plugins.pump.insight.LocalInsightPlugin import info.nightscout.androidaps.plugins.pump.medtronic.MedtronicPumpPlugin import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin import info.nightscout.androidaps.plugins.sensitivity.SensitivityAAPSPlugin import info.nightscout.androidaps.plugins.sensitivity.SensitivityOref1Plugin import info.nightscout.androidaps.plugins.sensitivity.SensitivityWeightedAveragePlugin import info.nightscout.androidaps.plugins.source.DexcomPlugin import info.nightscout.androidaps.plugins.source.EversensePlugin import info.nightscout.androidaps.plugins.source.GlimpPlugin import info.nightscout.androidaps.plugins.source.PoctechPlugin import info.nightscout.androidaps.plugins.source.TomatoPlugin import info.nightscout.androidaps.utils.OKDialog.show import info.nightscout.androidaps.utils.SafeParse import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.sharedPreferences.SP import javax.inject.Inject class MyPreferenceFragment : PreferenceFragmentCompat(), OnSharedPreferenceChangeListener, HasAndroidInjector { private var pluginId = -1 @Inject lateinit var rxBus: RxBusWrapper @Inject lateinit var resourceHelper: ResourceHelper @Inject lateinit var sp: SP @Inject lateinit var profileFunction: ProfileFunction @Inject lateinit var pluginStore: PluginStore @Inject lateinit var automationPlugin: AutomationPlugin @Inject lateinit var danaRPlugin: DanaRPlugin @Inject lateinit var danaRKoreanPlugin: DanaRKoreanPlugin @Inject lateinit var danaRv2Plugin: DanaRv2Plugin @Inject lateinit var danaRSPlugin: DanaRSPlugin @Inject lateinit var careportalPlugin: CareportalPlugin @Inject lateinit var comboPlugin: ComboPlugin @Inject lateinit var insulinOrefFreePeakPlugin: InsulinOrefFreePeakPlugin @Inject lateinit var loopPlugin: LoopPlugin @Inject lateinit var localInsightPlugin: LocalInsightPlugin @Inject lateinit var medtronicPumpPlugin: MedtronicPumpPlugin @Inject lateinit var nsClientPlugin: NSClientPlugin @Inject lateinit var openAPSAMAPlugin: OpenAPSAMAPlugin @Inject lateinit var openAPSMAPlugin: OpenAPSMAPlugin @Inject lateinit var openAPSSMBPlugin: OpenAPSSMBPlugin @Inject lateinit var safetyPlugin: SafetyPlugin @Inject lateinit var sensitivityAAPSPlugin: SensitivityAAPSPlugin @Inject lateinit var sensitivityOref0Plugin: SensitivityOref1Plugin @Inject lateinit var sensitivityOref1Plugin: SensitivityOref1Plugin @Inject lateinit var sensitivityWeightedAveragePlugin: SensitivityWeightedAveragePlugin @Inject lateinit var dexcomPlugin: DexcomPlugin @Inject lateinit var eversensePlugin: EversensePlugin @Inject lateinit var glimpPlugin: GlimpPlugin @Inject lateinit var poctechPlugin: PoctechPlugin @Inject lateinit var tomatoPlugin: TomatoPlugin @Inject lateinit var smsCommunicatorPlugin: SmsCommunicatorPlugin @Inject lateinit var statusLinePlugin: StatusLinePlugin @Inject lateinit var tidepoolPlugin: TidepoolPlugin @Inject lateinit var virtualPumpPlugin: VirtualPumpPlugin @Inject lateinit var wearPlugin: WearPlugin @Inject lateinit var maintenancePlugin: MaintenancePlugin @Inject lateinit var androidInjector: DispatchingAndroidInjector override fun androidInjector(): AndroidInjector = androidInjector override fun onAttach(context: Context) { AndroidSupportInjection.inject(this) super.onAttach(context) } override fun setArguments(args: Bundle?) { super.setArguments(args) pluginId = args?.getInt("id") ?: -1 } override fun onSaveInstanceState(outState: Bundle) { super.onSaveInstanceState(outState) outState.putInt("id", pluginId) } override fun onDestroy() { super.onDestroy() PreferenceManager .getDefaultSharedPreferences(context) .unregisterOnSharedPreferenceChangeListener(this) } private fun addPreferencesFromResourceIfEnabled(p: PluginBase?, rootKey: String?, enabled: Boolean) { if (enabled) addPreferencesFromResourceIfEnabled(p, rootKey) } private fun addPreferencesFromResourceIfEnabled(p: PluginBase?, rootKey: String?) { if (p!!.isEnabled() && p.preferencesId != -1) addPreferencesFromResource(p.preferencesId, rootKey) } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) PreferenceManager .getDefaultSharedPreferences(context) .registerOnSharedPreferenceChangeListener(this) } override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { (savedInstanceState ?: arguments)?.let { bundle -> if (bundle.containsKey("id")) { pluginId = bundle.getInt("id") } } if (pluginId != -1) { addPreferencesFromResource(pluginId, rootKey) } else { addPreferencesFromResource(R.xml.pref_general, rootKey) addPreferencesFromResource(R.xml.pref_overview, rootKey) addPreferencesFromResourceIfEnabled(safetyPlugin, rootKey) addPreferencesFromResourceIfEnabled(eversensePlugin, rootKey) addPreferencesFromResourceIfEnabled(dexcomPlugin, rootKey) addPreferencesFromResourceIfEnabled(tomatoPlugin, rootKey) addPreferencesFromResourceIfEnabled(poctechPlugin, rootKey) addPreferencesFromResourceIfEnabled(glimpPlugin, rootKey) addPreferencesFromResourceIfEnabled(careportalPlugin, rootKey) addPreferencesFromResourceIfEnabled(loopPlugin, rootKey, Config.APS) addPreferencesFromResourceIfEnabled(openAPSMAPlugin, rootKey, Config.APS) addPreferencesFromResourceIfEnabled(openAPSAMAPlugin, rootKey, Config.APS) addPreferencesFromResourceIfEnabled(openAPSSMBPlugin, rootKey, Config.APS) addPreferencesFromResourceIfEnabled(sensitivityAAPSPlugin, rootKey) addPreferencesFromResourceIfEnabled(sensitivityWeightedAveragePlugin, rootKey) addPreferencesFromResourceIfEnabled(sensitivityOref0Plugin, rootKey) addPreferencesFromResourceIfEnabled(sensitivityOref1Plugin, rootKey) addPreferencesFromResourceIfEnabled(danaRPlugin, rootKey, Config.PUMPDRIVERS) addPreferencesFromResourceIfEnabled(danaRKoreanPlugin, rootKey, Config.PUMPDRIVERS) addPreferencesFromResourceIfEnabled(danaRv2Plugin, rootKey, Config.PUMPDRIVERS) addPreferencesFromResourceIfEnabled(danaRSPlugin, rootKey, Config.PUMPDRIVERS) addPreferencesFromResourceIfEnabled(localInsightPlugin, rootKey, Config.PUMPDRIVERS) addPreferencesFromResourceIfEnabled(comboPlugin, rootKey, Config.PUMPDRIVERS) addPreferencesFromResourceIfEnabled(medtronicPumpPlugin, rootKey, Config.PUMPDRIVERS) addPreferencesFromResourceIfEnabled(virtualPumpPlugin, rootKey, !Config.NSCLIENT) addPreferencesFromResourceIfEnabled(insulinOrefFreePeakPlugin, rootKey) addPreferencesFromResourceIfEnabled(nsClientPlugin, rootKey) addPreferencesFromResourceIfEnabled(tidepoolPlugin, rootKey) addPreferencesFromResourceIfEnabled(smsCommunicatorPlugin, rootKey) addPreferencesFromResourceIfEnabled(automationPlugin, rootKey) addPreferencesFromResourceIfEnabled(wearPlugin, rootKey) addPreferencesFromResourceIfEnabled(statusLinePlugin, rootKey) addPreferencesFromResource(R.xml.pref_alerts, rootKey) // TODO not organized well addPreferencesFromResource(R.xml.pref_datachoices, rootKey) addPreferencesFromResourceIfEnabled(maintenancePlugin, rootKey) } initSummary(preferenceScreen) for (plugin in pluginStore.plugins) { plugin.preprocessPreferences(this) } } override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) { rxBus.send(EventPreferenceChange(key)) if (key == resourceHelper.gs(R.string.key_language)) { rxBus.send(EventRebuildTabs(true)) //recreate() does not update language so better close settings activity?.finish() } if (key == resourceHelper.gs(R.string.key_short_tabtitles)) { rxBus.send(EventRebuildTabs()) } if (key == resourceHelper.gs(R.string.key_units)) { activity?.recreate() return } if (key == resourceHelper.gs(R.string.key_openapsama_useautosens) && sp.getBoolean(R.string.key_openapsama_useautosens, false)) activity?.let { show(it, resourceHelper.gs(R.string.configbuilder_sensitivity), resourceHelper.gs(R.string.sensitivity_warning)) } updatePrefSummary(findPreference(key)) } private fun addPreferencesFromResource(@XmlRes preferencesResId: Int, key: String?) { val xmlRoot = preferenceManager.inflateFromResource(context, preferencesResId, null) val root: Preference? if (key != null) { root = xmlRoot.findPreference(key) if (root == null) return require(root is PreferenceScreen) { ("Preference object with key " + key + " is not a PreferenceScreen") } preferenceScreen = root } else { addPreferencesFromResource(preferencesResId) } } private fun adjustUnitDependentPrefs(pref: Preference) { // convert preferences values to current units val unitDependent = arrayOf( resourceHelper.gs(R.string.key_hypo_target), resourceHelper.gs(R.string.key_activity_target), resourceHelper.gs(R.string.key_eatingsoon_target), resourceHelper.gs(R.string.key_high_mark), resourceHelper.gs(R.string.key_low_mark) ) if (listOf(*unitDependent).contains(pref.key)) { val editTextPref = pref as EditTextPreference val converted = Profile.toCurrentUnitsString(profileFunction, SafeParse.stringToDouble(editTextPref.text)) editTextPref.summary = converted editTextPref.text = converted } } private fun updatePrefSummary(pref: Preference?) { if (pref is ListPreference) { pref.setSummary(pref.entry) } if (pref is EditTextPreference) { if (pref.getKey().contains("password") || pref.getKey().contains("secret")) { pref.setSummary("******") } else if (pref.text != null) { pref.dialogMessage = pref.dialogMessage pref.setSummary(pref.text) } else { for (plugin in pluginStore.plugins) { plugin.updatePreferenceSummary(pref) } } } pref?.let { adjustUnitDependentPrefs(it) } } private fun initSummary(p: Preference) { p.isIconSpaceReserved = false // remove extra spacing on left after migration to androidx if (p is PreferenceGroup) { for (i in 0 until p.preferenceCount) { initSummary(p.getPreference(i)) } } else { updatePrefSummary(p) } } }