Merge pull request #2312 from MilosKozak/dagger3a

Dagger3a
This commit is contained in:
Milos Kozak 2019-12-27 10:28:19 +01:00 committed by GitHub
commit 8f7c4fe145
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
265 changed files with 8502 additions and 7269 deletions

View file

@ -0,0 +1,137 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<option name="AUTODETECT_INDENTS" value="false" />
<AndroidXmlCodeStyleSettings>
<option name="ARRANGEMENT_SETTINGS_MIGRATED_TO_191" value="true" />
</AndroidXmlCodeStyleSettings>
<JetCodeStyleSettings>
<option name="ALIGN_IN_COLUMNS_CASE_BRANCH" value="true" />
<option name="NAME_COUNT_TO_USE_STAR_IMPORT" value="6" />
<option name="NAME_COUNT_TO_USE_STAR_IMPORT_FOR_MEMBERS" value="6" />
<option name="BLANK_LINES_AROUND_BLOCK_WHEN_BRANCHES" value="1" />
</JetCodeStyleSettings>
<codeStyleSettings language="XML">
<indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="4" />
</indentOptions>
<arrangement>
<rules>
<section>
<rule>
<match>
<AND>
<NAME>xmlns:android</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>xmlns:.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:id</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:name</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>name</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>style</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
<order>ANDROID_ATTRIBUTE_ORDER</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>.*</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
</rules>
</arrangement>
</codeStyleSettings>
<codeStyleSettings language="kotlin">
<option name="LINE_COMMENT_AT_FIRST_COLUMN" value="false" />
<option name="LINE_COMMENT_ADD_SPACE" value="true" />
<option name="KEEP_BLANK_LINES_IN_DECLARATIONS" value="1" />
<option name="KEEP_BLANK_LINES_IN_CODE" value="1" />
<option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="1" />
<option name="BLANK_LINES_AFTER_CLASS_HEADER" value="1" />
<indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="4" />
</indentOptions>
</codeStyleSettings>
</code_scheme>
</component>

View file

@ -0,0 +1,5 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
</state>
</component>

View file

@ -51,12 +51,11 @@
</activity> </activity>
<activity android:name=".activities.PreferencesActivity" /> <activity android:name=".activities.PreferencesActivity" />
<activity <activity
android:name=".plugins.general.overview.dialogs.BolusProgressHelperActivity" android:name=".activities.BolusProgressHelperActivity"
android:theme="@style/Theme.AppCompat.Translucent" /> android:theme="@style/Theme.AppCompat.Translucent" />
<activity <activity
android:name=".plugins.general.overview.dialogs.ErrorHelperActivity" android:name=".activities.ErrorHelperActivity"
android:theme="@style/Theme.AppCompat.Translucent" /> android:theme="@style/Theme.AppCompat.Translucent" />
<activity android:name=".activities.AgreementActivity" />
<activity android:name=".plugins.pump.danaR.activities.DanaRHistoryActivity" /> <activity android:name=".plugins.pump.danaR.activities.DanaRHistoryActivity" />
<activity android:name=".plugins.pump.danaR.activities.DanaRUserOptionsActivity" /> <activity android:name=".plugins.pump.danaR.activities.DanaRUserOptionsActivity" />
<activity android:name=".activities.TDDStatsActivity" /> <activity android:name=".activities.TDDStatsActivity" />
@ -116,7 +115,7 @@
<!-- Auto start --> <!-- Auto start -->
<receiver <receiver
android:name=".plugins.general.nsclient.receivers.AutoStartReceiver" android:name=".receivers.AutoStartReceiver"
android:enabled="true" android:enabled="true"
android:exported="true"> android:exported="true">
<intent-filter> <intent-filter>
@ -124,16 +123,6 @@
</intent-filter> </intent-filter>
</receiver> </receiver>
<!-- NSClient -->
<receiver
android:name=".plugins.general.nsclient.receivers.DBAccessReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="info.nightscout.client.DBACCESS" />
</intent-filter>
</receiver>
<!-- Network change local receiver --> <!-- Network change local receiver -->
<receiver android:name=".receivers.NetworkChangeReceiver"> <receiver android:name=".receivers.NetworkChangeReceiver">
<intent-filter> <intent-filter>

View file

@ -25,8 +25,6 @@ public class Constants {
public static final int hoursToKeepInDatabase = 72; public static final int hoursToKeepInDatabase = 72;
public static final int daysToKeepHistoryInDatabase = 30; public static final int daysToKeepHistoryInDatabase = 30;
public static final long keepAliveMsecs = 5 * 60 * 1000L;
// SMS COMMUNICATOR // SMS COMMUNICATOR
public static final long remoteBolusMinDistance = 15 * 60 * 1000L; public static final long remoteBolusMinDistance = 15 * 60 * 1000L;
@ -82,4 +80,11 @@ public class Constants {
public static final double LOWMARK = 76.0; public static final double LOWMARK = 76.0;
public static final double HIGHMARK = 180.0; public static final double HIGHMARK = 180.0;
// STATISTICS
public static final double STATS_TARGET_LOW_MMOL = 3.9;
public static final double STATS_TARGET_HIGH_MMOL = 7.8;
public static final double STATS_RANGE_LOW_MMOL = 3.9;
public static final double STATS_RANGE_HIGH_MMOL = 10.0;
} }

View file

@ -37,13 +37,17 @@ import com.joanzapata.iconify.fonts.FontAwesomeModule;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import dagger.android.AndroidInjection; import dagger.android.AndroidInjection;
import dagger.android.AndroidInjector;
import dagger.android.DispatchingAndroidInjector;
import dagger.android.HasAndroidInjector;
import info.nightscout.androidaps.activities.HistoryBrowseActivity; import info.nightscout.androidaps.activities.HistoryBrowseActivity;
import info.nightscout.androidaps.activities.NoSplashAppCompatActivity; import info.nightscout.androidaps.activities.NoSplashAppCompatActivity;
import info.nightscout.androidaps.activities.PreferencesActivity; import info.nightscout.androidaps.activities.PreferencesActivity;
import info.nightscout.androidaps.activities.SingleFragmentActivity; import info.nightscout.androidaps.activities.SingleFragmentActivity;
import info.nightscout.androidaps.activities.StatsActivity; import info.nightscout.androidaps.activities.StatsActivity;
import info.nightscout.androidaps.activities.SurveyActivity;
import info.nightscout.androidaps.events.EventAppExit; import info.nightscout.androidaps.events.EventAppExit;
import info.nightscout.androidaps.events.EventPreferenceChange; import info.nightscout.androidaps.events.EventPreferenceChange;
import info.nightscout.androidaps.events.EventRebuildTabs; import info.nightscout.androidaps.events.EventRebuildTabs;
@ -54,24 +58,33 @@ import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin;
import info.nightscout.androidaps.plugins.bus.RxBus; import info.nightscout.androidaps.plugins.bus.RxBus;
import info.nightscout.androidaps.plugins.constraints.versionChecker.VersionCheckerUtilsKt; import info.nightscout.androidaps.plugins.constraints.versionChecker.VersionCheckerUtilsKt;
import info.nightscout.androidaps.plugins.general.nsclient.data.NSSettingsStatus; import info.nightscout.androidaps.plugins.general.nsclient.data.NSSettingsStatus;
import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin;
import info.nightscout.androidaps.setupwizard.SetupWizardActivity; import info.nightscout.androidaps.setupwizard.SetupWizardActivity;
import info.nightscout.androidaps.tabs.TabPageAdapter; import info.nightscout.androidaps.tabs.TabPageAdapter;
import info.nightscout.androidaps.utils.AndroidPermission; import info.nightscout.androidaps.utils.AndroidPermission;
import info.nightscout.androidaps.utils.FabricPrivacy; import info.nightscout.androidaps.utils.FabricPrivacy;
import info.nightscout.androidaps.utils.LocaleHelper; import info.nightscout.androidaps.utils.LocaleHelper;
import info.nightscout.androidaps.utils.OKDialog;
import info.nightscout.androidaps.utils.PasswordProtection; import info.nightscout.androidaps.utils.PasswordProtection;
import info.nightscout.androidaps.utils.SP; import info.nightscout.androidaps.utils.SP;
import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable; import io.reactivex.disposables.CompositeDisposable;
public class MainActivity extends NoSplashAppCompatActivity { public class MainActivity extends NoSplashAppCompatActivity implements HasAndroidInjector {
private static Logger log = LoggerFactory.getLogger(L.CORE); private static Logger log = LoggerFactory.getLogger(L.CORE);
@Inject
DispatchingAndroidInjector<Object> androidInjector;
private CompositeDisposable disposable = new CompositeDisposable(); private CompositeDisposable disposable = new CompositeDisposable();
private ActionBarDrawerToggle actionBarDrawerToggle; private ActionBarDrawerToggle actionBarDrawerToggle;
private MenuItem pluginPreferencesMenuItem; private MenuItem pluginPreferencesMenuItem;
@Inject
SmsCommunicatorPlugin smsCommunicatorPlugin;
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
AndroidInjection.inject(this); AndroidInjection.inject(this);
@ -94,8 +107,6 @@ public class MainActivity extends NoSplashAppCompatActivity {
// initialize screen wake lock // initialize screen wake lock
processPreferenceChange(new EventPreferenceChange(R.string.key_keep_screen_on)); processPreferenceChange(new EventPreferenceChange(R.string.key_keep_screen_on));
doMigrations();
final ViewPager viewPager = findViewById(R.id.pager); final ViewPager viewPager = findViewById(R.id.pager);
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override @Override
@ -141,7 +152,7 @@ public class MainActivity extends NoSplashAppCompatActivity {
.subscribe(this::processPreferenceChange, FabricPrivacy::logException) .subscribe(this::processPreferenceChange, FabricPrivacy::logException)
); );
if (!SP.getBoolean(R.string.key_setupwizard_processed, false) || !SP.contains(R.string.key_units)) { if (!SP.getBoolean(R.string.key_setupwizard_processed, false)) {
Intent intent = new Intent(this, SetupWizardActivity.class); Intent intent = new Intent(this, SetupWizardActivity.class);
startActivity(intent); startActivity(intent);
} }
@ -150,7 +161,7 @@ public class MainActivity extends NoSplashAppCompatActivity {
AndroidPermission.notifyForBatteryOptimizationPermission(this); AndroidPermission.notifyForBatteryOptimizationPermission(this);
if (Config.PUMPDRIVERS) { if (Config.PUMPDRIVERS) {
AndroidPermission.notifyForLocationPermissions(this); AndroidPermission.notifyForLocationPermissions(this);
AndroidPermission.notifyForSMSPermissions(this); AndroidPermission.notifyForSMSPermissions(this, smsCommunicatorPlugin);
} }
} }
@ -235,17 +246,6 @@ public class MainActivity extends NoSplashAppCompatActivity {
} }
} }
private void doMigrations() {
// guarantee that the unreachable threshold is at least 30 and of type String
// Added in 1.57 at 21.01.2018
int unreachable_threshold = SP.getInt(R.string.key_pump_unreachable_threshold, 30);
SP.remove(R.string.key_pump_unreachable_threshold);
if (unreachable_threshold < 30) unreachable_threshold = 30;
SP.putString(R.string.key_pump_unreachable_threshold, Integer.toString(unreachable_threshold));
}
@Override @Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults); super.onRequestPermissionsResult(requestCode, permissions, grantResults);
@ -254,10 +254,7 @@ public class MainActivity extends NoSplashAppCompatActivity {
switch (requestCode) { switch (requestCode) {
case AndroidPermission.CASE_STORAGE: case AndroidPermission.CASE_STORAGE:
//show dialog after permission is granted //show dialog after permission is granted
AlertDialog.Builder alert = new AlertDialog.Builder(this); OKDialog.show(this, "", MainApp.gs(R.string.alert_dialog_storage_permission_text));
alert.setMessage(R.string.alert_dialog_storage_permission_text);
alert.setPositiveButton(R.string.ok, null);
alert.show();
break; break;
case AndroidPermission.CASE_LOCATION: case AndroidPermission.CASE_LOCATION:
case AndroidPermission.CASE_SMS: case AndroidPermission.CASE_SMS:
@ -331,9 +328,7 @@ public class MainActivity extends NoSplashAppCompatActivity {
return true; return true;
case R.id.nav_exit: case R.id.nav_exit:
log.debug("Exiting"); log.debug("Exiting");
MainApp.instance().stopKeepAliveService();
RxBus.INSTANCE.send(new EventAppExit()); RxBus.INSTANCE.send(new EventAppExit());
MainApp.closeDbHelper();
finish(); finish();
System.runFinalization(); System.runFinalization();
System.exit(0); System.exit(0);
@ -358,4 +353,13 @@ public class MainActivity extends NoSplashAppCompatActivity {
} }
return actionBarDrawerToggle.onOptionsItemSelected(item); return actionBarDrawerToggle.onOptionsItemSelected(item);
} }
/**
* Returns an {@link AndroidInjector}.
*/
@Override
public AndroidInjector<Object> androidInjector() {
return androidInjector;
}
} }

View file

@ -1,11 +1,13 @@
package info.nightscout.androidaps; package info.nightscout.androidaps;
import android.content.BroadcastReceiver;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.content.res.Resources; import android.content.res.Resources;
import android.os.SystemClock; import android.os.SystemClock;
import androidx.annotation.ColorRes;
import androidx.annotation.PluralsRes; import androidx.annotation.PluralsRes;
import androidx.annotation.StringRes;
import androidx.core.content.ContextCompat;
import androidx.localbroadcastmanager.content.LocalBroadcastManager; import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import com.crashlytics.android.Crashlytics; import com.crashlytics.android.Crashlytics;
@ -14,6 +16,7 @@ import com.j256.ormlite.android.apptools.OpenHelperManager;
import net.danlew.android.joda.JodaTimeAndroid; import net.danlew.android.joda.JodaTimeAndroid;
import org.json.JSONException;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -25,6 +28,7 @@ import javax.inject.Inject;
import dagger.android.AndroidInjector; import dagger.android.AndroidInjector;
import dagger.android.DaggerApplication; import dagger.android.DaggerApplication;
import info.nightscout.androidaps.data.ConstraintChecker; import info.nightscout.androidaps.data.ConstraintChecker;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.db.DatabaseHelper; import info.nightscout.androidaps.db.DatabaseHelper;
import info.nightscout.androidaps.dependencyInjection.DaggerAppComponent; import info.nightscout.androidaps.dependencyInjection.DaggerAppComponent;
import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.PluginBase;
@ -36,6 +40,7 @@ import info.nightscout.androidaps.plugins.aps.openAPSAMA.OpenAPSAMAPlugin;
import info.nightscout.androidaps.plugins.aps.openAPSMA.OpenAPSMAPlugin; import info.nightscout.androidaps.plugins.aps.openAPSMA.OpenAPSMAPlugin;
import info.nightscout.androidaps.plugins.aps.openAPSSMB.OpenAPSSMBPlugin; import info.nightscout.androidaps.plugins.aps.openAPSSMB.OpenAPSSMBPlugin;
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
import info.nightscout.androidaps.plugins.constraints.dstHelper.DstHelperPlugin; import info.nightscout.androidaps.plugins.constraints.dstHelper.DstHelperPlugin;
import info.nightscout.androidaps.plugins.constraints.objectives.ObjectivesPlugin; import info.nightscout.androidaps.plugins.constraints.objectives.ObjectivesPlugin;
import info.nightscout.androidaps.plugins.constraints.safety.SafetyPlugin; import info.nightscout.androidaps.plugins.constraints.safety.SafetyPlugin;
@ -50,8 +55,6 @@ import info.nightscout.androidaps.plugins.general.maintenance.LoggerUtils;
import info.nightscout.androidaps.plugins.general.maintenance.MaintenancePlugin; import info.nightscout.androidaps.plugins.general.maintenance.MaintenancePlugin;
import info.nightscout.androidaps.plugins.general.nsclient.NSClientPlugin; import info.nightscout.androidaps.plugins.general.nsclient.NSClientPlugin;
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload; import info.nightscout.androidaps.plugins.general.nsclient.NSUpload;
import info.nightscout.androidaps.plugins.general.nsclient.receivers.AckAlarmReceiver;
import info.nightscout.androidaps.plugins.general.nsclient.receivers.DBAccessReceiver;
import info.nightscout.androidaps.plugins.general.overview.OverviewPlugin; import info.nightscout.androidaps.plugins.general.overview.OverviewPlugin;
import info.nightscout.androidaps.plugins.general.persistentNotification.PersistentNotificationPlugin; import info.nightscout.androidaps.plugins.general.persistentNotification.PersistentNotificationPlugin;
import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin; import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin;
@ -94,7 +97,7 @@ import info.nightscout.androidaps.services.Intents;
import info.nightscout.androidaps.utils.ActivityMonitor; import info.nightscout.androidaps.utils.ActivityMonitor;
import info.nightscout.androidaps.utils.FabricPrivacy; import info.nightscout.androidaps.utils.FabricPrivacy;
import info.nightscout.androidaps.utils.LocaleHelper; import info.nightscout.androidaps.utils.LocaleHelper;
import info.nightscout.androidaps.utils.sharedPreferences.SPImpl; import info.nightscout.androidaps.utils.SP;
import io.fabric.sdk.android.Fabric; import io.fabric.sdk.android.Fabric;
import static info.nightscout.androidaps.plugins.constraints.versionChecker.VersionCheckerUtilsKt.triggerCheckVersion; import static info.nightscout.androidaps.plugins.constraints.versionChecker.VersionCheckerUtilsKt.triggerCheckVersion;
@ -102,7 +105,6 @@ import static info.nightscout.androidaps.plugins.constraints.versionChecker.Vers
public class MainApp extends DaggerApplication { public class MainApp extends DaggerApplication {
static Logger log = LoggerFactory.getLogger(L.CORE); static Logger log = LoggerFactory.getLogger(L.CORE);
static KeepAliveReceiver keepAliveReceiver;
static MainApp sInstance; static MainApp sInstance;
public static Resources sResources; public static Resources sResources;
@ -115,18 +117,18 @@ public class MainApp extends DaggerApplication {
static ArrayList<PluginBase> pluginsList = null; static ArrayList<PluginBase> pluginsList = null;
static DataReceiver dataReceiver = new DataReceiver(); static DataReceiver dataReceiver = new DataReceiver();
static NSAlarmReceiver alarmReciever = new NSAlarmReceiver(); static NSAlarmReceiver alarmReceiver = new NSAlarmReceiver();
static AckAlarmReceiver ackAlarmReciever = new AckAlarmReceiver();
static DBAccessReceiver dbAccessReciever = new DBAccessReceiver();
LocalBroadcastManager lbm;
BroadcastReceiver btReceiver;
TimeDateOrTZChangeReceiver timeDateOrTZChangeReceiver; TimeDateOrTZChangeReceiver timeDateOrTZChangeReceiver;
public static boolean devBranch; public static boolean devBranch;
public static boolean engineeringMode; public static boolean engineeringMode;
@Inject @Inject ConfigBuilderPlugin configBuilderPlugin;
InsulinOrefFreePeakPlugin insulinOrefFreePeakPlugin;
@Inject InsulinOrefFreePeakPlugin insulinOrefFreePeakPlugin;
@Inject InsulinOrefRapidActingPlugin insulinOrefRapidActingPlugin;
@Inject InsulinOrefUltraRapidActingPlugin insulinOrefUltraRapidActingPlugin;
@Inject SmsCommunicatorPlugin smsCommunicatorPlugin;
@Override @Override
public void onCreate() { public void onCreate() {
@ -159,7 +161,7 @@ public class MainApp extends DaggerApplication {
registerActivityLifecycleCallbacks(ActivityMonitor.INSTANCE); registerActivityLifecycleCallbacks(ActivityMonitor.INSTANCE);
mFirebaseAnalytics = FirebaseAnalytics.getInstance(this); mFirebaseAnalytics = FirebaseAnalytics.getInstance(this);
mFirebaseAnalytics.setAnalyticsCollectionEnabled(!Boolean.getBoolean("disableFirebase")); mFirebaseAnalytics.setAnalyticsCollectionEnabled(!Boolean.getBoolean("disableFirebase") && FabricPrivacy.fabricEnabled());
JodaTimeAndroid.init(this); JodaTimeAndroid.init(this);
@ -177,7 +179,6 @@ public class MainApp extends DaggerApplication {
//trigger here to see the new version on app start after an update //trigger here to see the new version on app start after an update
triggerCheckVersion(); triggerCheckVersion();
//setBTReceiver();
if (pluginsList == null) { if (pluginsList == null) {
pluginsList = new ArrayList<>(); pluginsList = new ArrayList<>();
@ -185,8 +186,8 @@ public class MainApp extends DaggerApplication {
pluginsList.add(OverviewPlugin.INSTANCE); pluginsList.add(OverviewPlugin.INSTANCE);
pluginsList.add(IobCobCalculatorPlugin.getPlugin()); pluginsList.add(IobCobCalculatorPlugin.getPlugin());
if (!Config.NSCLIENT) pluginsList.add(ActionsPlugin.INSTANCE); if (!Config.NSCLIENT) pluginsList.add(ActionsPlugin.INSTANCE);
pluginsList.add(InsulinOrefRapidActingPlugin.getPlugin()); pluginsList.add(insulinOrefRapidActingPlugin);
pluginsList.add(InsulinOrefUltraRapidActingPlugin.getPlugin()); pluginsList.add(insulinOrefUltraRapidActingPlugin);
pluginsList.add(insulinOrefFreePeakPlugin); pluginsList.add(insulinOrefFreePeakPlugin);
pluginsList.add(SensitivityOref0Plugin.getPlugin()); pluginsList.add(SensitivityOref0Plugin.getPlugin());
pluginsList.add(SensitivityAAPSPlugin.getPlugin()); pluginsList.add(SensitivityAAPSPlugin.getPlugin());
@ -223,7 +224,7 @@ public class MainApp extends DaggerApplication {
pluginsList.add(SourceTomatoPlugin.getPlugin()); pluginsList.add(SourceTomatoPlugin.getPlugin());
pluginsList.add(SourceEversensePlugin.getPlugin()); pluginsList.add(SourceEversensePlugin.getPlugin());
pluginsList.add(RandomBgPlugin.INSTANCE); pluginsList.add(RandomBgPlugin.INSTANCE);
if (!Config.NSCLIENT) pluginsList.add(SmsCommunicatorPlugin.INSTANCE); if (!Config.NSCLIENT) pluginsList.add(smsCommunicatorPlugin);
pluginsList.add(FoodPlugin.getPlugin()); pluginsList.add(FoodPlugin.getPlugin());
pluginsList.add(WearPlugin.initPlugin(this)); pluginsList.add(WearPlugin.initPlugin(this));
@ -234,29 +235,56 @@ public class MainApp extends DaggerApplication {
pluginsList.add(MaintenancePlugin.initPlugin(this)); pluginsList.add(MaintenancePlugin.initPlugin(this));
pluginsList.add(AutomationPlugin.INSTANCE); pluginsList.add(AutomationPlugin.INSTANCE);
pluginsList.add(ConfigBuilderPlugin.getPlugin()); pluginsList.add(configBuilderPlugin);
pluginsList.add(DstHelperPlugin.getPlugin()); pluginsList.add(DstHelperPlugin.getPlugin());
ConfigBuilderPlugin.getPlugin().initialize(); configBuilderPlugin.initialize();
} }
NSUpload.uploadAppStart(); NSUpload.uploadAppStart();
final PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); final PumpInterface pump = configBuilderPlugin.getActivePump();
if (pump != null) { if (pump != null) {
new Thread(() -> { new Thread(() -> {
SystemClock.sleep(5000); SystemClock.sleep(5000);
ConfigBuilderPlugin.getPlugin().getCommandQueue().readStatus("Initialization", null); configBuilderPlugin.getCommandQueue().readStatus("Initialization", null);
startKeepAliveService();
}).start(); }).start();
} }
new Thread(() -> KeepAliveReceiver.setAlarm(this)).start();
doMigrations();
}
private void doMigrations() {
// guarantee that the unreachable threshold is at least 30 and of type String
// Added in 1.57 at 21.01.2018
int unreachable_threshold = SP.getInt(R.string.key_pump_unreachable_threshold, 30);
SP.remove(R.string.key_pump_unreachable_threshold);
if (unreachable_threshold < 30) unreachable_threshold = 30;
SP.putString(R.string.key_pump_unreachable_threshold, Integer.toString(unreachable_threshold));
// 2.5 -> 2.6
if (!SP.contains(R.string.key_units)) {
String newUnits = Constants.MGDL;
Profile p = ProfileFunctions.getInstance().getProfile();
if (p != null && p.getData() != null && p.getData().has("units")) {
try {
newUnits = p.getData().getString("units");
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
}
SP.putString(R.string.key_units, newUnits);
}
} }
@Override @Override
protected AndroidInjector<? extends DaggerApplication> applicationInjector() { protected AndroidInjector<? extends DaggerApplication> applicationInjector() {
return DaggerAppComponent return DaggerAppComponent
.builder() .builder()
.application(this) .application(this)
@ -264,7 +292,7 @@ public class MainApp extends DaggerApplication {
} }
private void registerLocalBroadcastReceiver() { private void registerLocalBroadcastReceiver() {
lbm = LocalBroadcastManager.getInstance(this); LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this);
lbm.registerReceiver(dataReceiver, new IntentFilter(Intents.ACTION_NEW_TREATMENT)); lbm.registerReceiver(dataReceiver, new IntentFilter(Intents.ACTION_NEW_TREATMENT));
lbm.registerReceiver(dataReceiver, new IntentFilter(Intents.ACTION_CHANGED_TREATMENT)); lbm.registerReceiver(dataReceiver, new IntentFilter(Intents.ACTION_CHANGED_TREATMENT));
lbm.registerReceiver(dataReceiver, new IntentFilter(Intents.ACTION_REMOVED_TREATMENT)); lbm.registerReceiver(dataReceiver, new IntentFilter(Intents.ACTION_REMOVED_TREATMENT));
@ -279,39 +307,21 @@ public class MainApp extends DaggerApplication {
lbm.registerReceiver(dataReceiver, new IntentFilter(Intents.ACTION_NEW_CAL)); lbm.registerReceiver(dataReceiver, new IntentFilter(Intents.ACTION_NEW_CAL));
//register alarms //register alarms
lbm.registerReceiver(alarmReciever, new IntentFilter(Intents.ACTION_ALARM)); lbm.registerReceiver(alarmReceiver, new IntentFilter(Intents.ACTION_ALARM));
lbm.registerReceiver(alarmReciever, new IntentFilter(Intents.ACTION_ANNOUNCEMENT)); lbm.registerReceiver(alarmReceiver, new IntentFilter(Intents.ACTION_ANNOUNCEMENT));
lbm.registerReceiver(alarmReciever, new IntentFilter(Intents.ACTION_CLEAR_ALARM)); lbm.registerReceiver(alarmReceiver, new IntentFilter(Intents.ACTION_CLEAR_ALARM));
lbm.registerReceiver(alarmReciever, new IntentFilter(Intents.ACTION_URGENT_ALARM)); lbm.registerReceiver(alarmReceiver, new IntentFilter(Intents.ACTION_URGENT_ALARM));
//register ack alarm
lbm.registerReceiver(ackAlarmReciever, new IntentFilter(Intents.ACTION_ACK_ALARM));
//register dbaccess
lbm.registerReceiver(dbAccessReciever, new IntentFilter(Intents.ACTION_DATABASE));
this.timeDateOrTZChangeReceiver = new TimeDateOrTZChangeReceiver(); this.timeDateOrTZChangeReceiver = new TimeDateOrTZChangeReceiver();
this.timeDateOrTZChangeReceiver.registerBroadcasts(this); this.timeDateOrTZChangeReceiver.registerBroadcasts(this);
} }
private void startKeepAliveService() { public static String gs(@StringRes int id) {
if (keepAliveReceiver == null) {
keepAliveReceiver = new KeepAliveReceiver();
keepAliveReceiver.setAlarm(this);
}
}
public void stopKeepAliveService() {
if (keepAliveReceiver != null)
KeepAliveReceiver.cancelAlarm(this);
}
public static String gs(int id) {
return sResources.getString(id); return sResources.getString(id);
} }
public static String gs(int id, Object... args) { public static String gs(@StringRes int id, Object... args) {
return sResources.getString(id, args); return sResources.getString(id, args);
} }
@ -319,8 +329,8 @@ public class MainApp extends DaggerApplication {
return sResources.getQuantityString(id, quantity, args); return sResources.getQuantityString(id, quantity, args);
} }
public static int gc(int id) { public static int gc(@ColorRes int id) {
return sResources.getColor(id); return ContextCompat.getColor(instance(), id);
} }
public static MainApp instance() { public static MainApp instance() {
@ -331,13 +341,6 @@ public class MainApp extends DaggerApplication {
return sDatabaseHelper; return sDatabaseHelper;
} }
public static void closeDbHelper() {
if (sDatabaseHelper != null) {
sDatabaseHelper.close();
sDatabaseHelper = null;
}
}
public static FirebaseAnalytics getFirebaseAnalytics() { public static FirebaseAnalytics getFirebaseAnalytics() {
return mFirebaseAnalytics; return mFirebaseAnalytics;
} }
@ -440,20 +443,12 @@ public class MainApp extends DaggerApplication {
public void onTerminate() { public void onTerminate() {
if (L.isEnabled(L.CORE)) if (L.isEnabled(L.CORE))
log.debug("onTerminate"); log.debug("onTerminate");
super.onTerminate();
if (sDatabaseHelper != null) {
sDatabaseHelper.close();
sDatabaseHelper = null;
}
if (btReceiver != null) { if (timeDateOrTZChangeReceiver != null)
unregisterReceiver(btReceiver);
}
if (timeDateOrTZChangeReceiver != null) {
unregisterReceiver(timeDateOrTZChangeReceiver); unregisterReceiver(timeDateOrTZChangeReceiver);
}
unregisterActivityLifecycleCallbacks(ActivityMonitor.INSTANCE); unregisterActivityLifecycleCallbacks(ActivityMonitor.INSTANCE);
KeepAliveReceiver.cancelAlarm(this);
super.onTerminate();
} }
public static int dpToPx(int dp) { public static int dpToPx(int dp) {

View file

@ -0,0 +1,14 @@
package info.nightscout.androidaps.activities
import android.os.Bundle
import info.nightscout.androidaps.dialogs.BolusProgressDialog
class BolusProgressHelperActivity : NoSplashAppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
BolusProgressDialog()
.setHelperActivity(this)
.setInsulin(intent.getDoubleExtra("insulin", 0.0))
.show(supportFragmentManager, "BolusProgress")
}
}

View file

@ -1,8 +1,8 @@
package info.nightscout.androidaps.plugins.general.overview.dialogs package info.nightscout.androidaps.activities
import android.os.Bundle import android.os.Bundle
import info.nightscout.androidaps.R import info.nightscout.androidaps.R
import info.nightscout.androidaps.activities.NoSplashAppCompatActivity import info.nightscout.androidaps.dialogs.ErrorDialog
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload import info.nightscout.androidaps.plugins.general.nsclient.NSUpload
import info.nightscout.androidaps.utils.SP import info.nightscout.androidaps.utils.SP

View file

@ -53,6 +53,9 @@ public class MyPreferenceFragment extends PreferenceFragment implements HasAndro
@Inject @Inject
InsulinOrefFreePeakPlugin insulinOrefFreePeakPlugin; InsulinOrefFreePeakPlugin insulinOrefFreePeakPlugin;
@Inject
SmsCommunicatorPlugin smsCommunicatorPlugin;
@Override @Override
public void setArguments(Bundle args) { public void setArguments(Bundle args) {
super.setArguments(args); super.setArguments(args);
@ -132,7 +135,7 @@ public class MyPreferenceFragment extends PreferenceFragment implements HasAndro
addPreferencesFromResourceIfEnabled(NSClientPlugin.getPlugin(), PluginType.GENERAL); addPreferencesFromResourceIfEnabled(NSClientPlugin.getPlugin(), PluginType.GENERAL);
addPreferencesFromResourceIfEnabled(TidepoolPlugin.INSTANCE, PluginType.GENERAL); addPreferencesFromResourceIfEnabled(TidepoolPlugin.INSTANCE, PluginType.GENERAL);
addPreferencesFromResourceIfEnabled(SmsCommunicatorPlugin.INSTANCE, PluginType.GENERAL); addPreferencesFromResourceIfEnabled(smsCommunicatorPlugin, PluginType.GENERAL);
addPreferencesFromResourceIfEnabled(AutomationPlugin.INSTANCE, PluginType.GENERAL); addPreferencesFromResourceIfEnabled(AutomationPlugin.INSTANCE, PluginType.GENERAL);
addPreferencesFromResource(R.xml.pref_others); addPreferencesFromResource(R.xml.pref_others);

View file

@ -25,7 +25,6 @@ import info.nightscout.androidaps.events.EventPreferenceChange;
import info.nightscout.androidaps.events.EventRebuildTabs; import info.nightscout.androidaps.events.EventRebuildTabs;
import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.PluginBase;
import info.nightscout.androidaps.plugins.bus.RxBus; import info.nightscout.androidaps.plugins.bus.RxBus;
import info.nightscout.androidaps.plugins.insulin.InsulinOrefFreePeakPlugin;
import info.nightscout.androidaps.utils.LocaleHelper; import info.nightscout.androidaps.utils.LocaleHelper;
import info.nightscout.androidaps.utils.OKDialog; import info.nightscout.androidaps.utils.OKDialog;
import info.nightscout.androidaps.utils.SP; import info.nightscout.androidaps.utils.SP;
@ -76,7 +75,7 @@ public class PreferencesActivity extends PreferenceActivity implements SharedPre
return; return;
} }
if (key.equals(MainApp.gs(R.string.key_openapsama_useautosens)) && SP.getBoolean(R.string.key_openapsama_useautosens, false)) { if (key.equals(MainApp.gs(R.string.key_openapsama_useautosens)) && SP.getBoolean(R.string.key_openapsama_useautosens, false)) {
OKDialog.show(this, MainApp.gs(R.string.configbuilder_sensitivity), MainApp.gs(R.string.sensitivity_warning), null); OKDialog.show(this, MainApp.gs(R.string.configbuilder_sensitivity), MainApp.gs(R.string.sensitivity_warning));
} }
updatePrefSummary(myPreferenceFragment.findPreference(key)); updatePrefSummary(myPreferenceFragment.findPreference(key));
} }

View file

@ -1,60 +0,0 @@
package info.nightscout.androidaps.activities;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.interfaces.PluginBase;
import info.nightscout.androidaps.utils.PasswordProtection;
public class SingleFragmentActivity extends AppCompatActivity {
private PluginBase plugin;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_single_fragment);
this.plugin = MainApp.getPluginsList().get(getIntent().getIntExtra("plugin", -1));
setTitle(plugin.getName());
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction().replace(R.id.frame_layout,
Fragment.instantiate(this, plugin.pluginDescription.getFragmentClass())).commit();
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
finish();
return true;
}
else if (item.getItemId() == R.id.nav_plugin_preferences) {
PasswordProtection.QueryPassword(this, R.string.settings_password, "settings_password", () -> {
Intent i = new Intent(this, PreferencesActivity.class);
i.putExtra("id", plugin.getPreferencesId());
startActivity(i);
}, null);
return true;
}
return false;
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
if (plugin.getPreferencesId() != -1)
getMenuInflater().inflate(R.menu.menu_single_fragment, menu);
return super.onCreateOptionsMenu(menu);
}
}

View file

@ -0,0 +1,53 @@
package info.nightscout.androidaps.activities
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import androidx.appcompat.app.AppCompatActivity
import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R
import info.nightscout.androidaps.interfaces.PluginBase
import info.nightscout.androidaps.utils.LocaleHelper
import info.nightscout.androidaps.utils.PasswordProtection
class SingleFragmentActivity : AppCompatActivity() {
private var plugin: PluginBase? = null
public override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_single_fragment)
plugin = MainApp.getPluginsList()[intent.getIntExtra("plugin", -1)]
title = plugin?.name
supportActionBar?.setDisplayHomeAsUpEnabled(true)
supportActionBar?.setDisplayShowHomeEnabled(true)
if (savedInstanceState == null) {
supportFragmentManager.beginTransaction().replace(R.id.frame_layout,
supportFragmentManager.fragmentFactory.instantiate(ClassLoader.getSystemClassLoader(), plugin?.pluginDescription?.fragmentClass!!)).commit()
}
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (item.itemId == android.R.id.home) {
finish()
return true
} else if (item.itemId == R.id.nav_plugin_preferences) {
PasswordProtection.QueryPassword(this, R.string.settings_password, "settings_password", Runnable {
val i = Intent(this, PreferencesActivity::class.java)
i.putExtra("id", plugin?.preferencesId)
startActivity(i)
}, null)
return true
}
return false
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
if (plugin?.preferencesId != -1) menuInflater.inflate(R.menu.menu_single_fragment, menu)
return super.onCreateOptionsMenu(menu)
}
public override fun attachBaseContext(newBase: Context) {
super.attachBaseContext(LocaleHelper.wrap(newBase))
}
}

View file

@ -9,7 +9,6 @@ import info.nightscout.androidaps.utils.TddCalculator
import info.nightscout.androidaps.utils.TirCalculator import info.nightscout.androidaps.utils.TirCalculator
import kotlinx.android.synthetic.main.stats_activity.* import kotlinx.android.synthetic.main.stats_activity.*
class StatsActivity : NoSplashAppCompatActivity() { class StatsActivity : NoSplashAppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
@ -22,10 +21,10 @@ class StatsActivity : NoSplashAppCompatActivity() {
ok.setOnClickListener { finish() } ok.setOnClickListener { finish() }
stats_reset.setOnClickListener { stats_reset.setOnClickListener {
OKDialog.showConfirmation(this, MainApp.gs(R.string.doyouwantresetstats)) { OKDialog.showConfirmation(this, MainApp.gs(R.string.doyouwantresetstats), Runnable {
ActivityMonitor.reset() ActivityMonitor.reset()
recreate() recreate()
} })
} }
} }
} }

View file

@ -4,25 +4,21 @@ import android.os.Bundle
import android.widget.ArrayAdapter import android.widget.ArrayAdapter
import com.google.firebase.auth.FirebaseAuth import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.database.FirebaseDatabase import com.google.firebase.database.FirebaseDatabase
import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.defaultProfile.DefaultProfile import info.nightscout.androidaps.data.defaultProfile.DefaultProfile
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions
import info.nightscout.androidaps.plugins.treatments.fragments.ProfileViewerDialog import info.nightscout.androidaps.dialogs.ProfileViewerDialog
import info.nightscout.androidaps.utils.* import info.nightscout.androidaps.utils.*
import kotlinx.android.synthetic.main.survey_fragment.* import kotlinx.android.synthetic.main.survey_activity.*
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory
import java.util.*
class SurveyActivity : NoSplashAppCompatActivity() { class SurveyActivity : NoSplashAppCompatActivity() {
private val log = LoggerFactory.getLogger(SurveyActivity::class.java) private val log = LoggerFactory.getLogger(SurveyActivity::class.java)
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContentView(R.layout.survey_fragment) setContentView(R.layout.survey_activity)
survey_id.text = InstanceId.instanceId() survey_id.text = InstanceId.instanceId()
@ -88,7 +84,7 @@ class SurveyActivity : NoSplashAppCompatActivity() {
.addOnCompleteListener(this) { task -> .addOnCompleteListener(this) { task ->
if (task.isSuccessful) { if (task.isSuccessful) {
log.debug("signInAnonymously:success") log.debug("signInAnonymously:success")
val user = auth.currentUser val user = auth.currentUser // TODO: do we need this, seems unused?
val database = FirebaseDatabase.getInstance().reference val database = FirebaseDatabase.getInstance().reference
database.child("survey").child(r.id).setValue(r) database.child("survey").child(r.id).setValue(r)

View file

@ -589,7 +589,7 @@ public class Profile {
public double getMaxDailyBasal() { public double getMaxDailyBasal() {
double max = 0d; double max = 0d;
for (int hour = 0; hour < 24; hour++) { for (int hour = 0; hour < 24; hour++) {
double value = getBasalTimeFromMidnight((Integer) (hour * 60 * 60)); double value = getBasalTimeFromMidnight(hour * 60 * 60);
if (value > max) max = value; if (value > max) max = value;
} }
return max; return max;

View file

@ -1,6 +1,7 @@
package info.nightscout.androidaps.data package info.nightscout.androidaps.data
import androidx.collection.ArrayMap import androidx.collection.ArrayMap
import info.nightscout.androidaps.utils.JsonHelper
import org.json.JSONException import org.json.JSONException
import org.json.JSONObject import org.json.JSONObject
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory
@ -40,21 +41,19 @@ class ProfileStore(val data: JSONObject) {
fun getSpecificProfile(profileName: String): Profile? { fun getSpecificProfile(profileName: String): Profile? {
var profile: Profile? = null var profile: Profile? = null
try {
getStore()?.let { store -> getStore()?.let { store ->
if (store.has(profileName)) { if (store.has(profileName)) {
profile = cachedObjects[profileName] profile = cachedObjects[profileName]
if (profile == null) { if (profile == null) {
val profileObject = store.getJSONObject(profileName) JsonHelper.safeGetJSONObject(store, profileName, null)?.let { profileObject ->
if (profileObject != null && profileObject.has("units")) { // take units from profile and if N/A from store
profile = Profile(profileObject, profileObject.getString("units")) JsonHelper.safeGetStringAllowNull(profileObject, "units", JsonHelper.safeGetString(data, "units"))?.let { units ->
profile = Profile(profileObject, units)
cachedObjects[profileName] = profile cachedObjects[profileName] = profile
} }
} }
} }
} }
} catch (e: JSONException) {
log.error("Unhandled exception", e)
} }
return profile return profile
} }

View file

@ -194,15 +194,6 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
return newVersion; return newVersion;
} }
/**
* Close the database connections and clear any cached DAOs.
*/
@Override
public void close() {
super.close();
}
public long size(String database) { public long size(String database) {
return DatabaseUtils.queryNumEntries(getReadableDatabase(), database); return DatabaseUtils.queryNumEntries(getReadableDatabase(), database);
} }
@ -1602,15 +1593,14 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
queryBuilder.limit(100L); queryBuilder.limit(100L);
Where where = queryBuilder.where(); Where where = queryBuilder.where();
where.ge("date", from); where.ge("date", from);
queryBuilder.setCountOf(true);
PreparedQuery<ProfileSwitch> preparedQuery = queryBuilder.prepare(); PreparedQuery<ProfileSwitch> preparedQuery = queryBuilder.prepare();
long count = daoProfileSwitch.countOf(preparedQuery);
// now do query of count + 1
queryBuilder = daoProfileSwitch.queryBuilder();
queryBuilder.orderBy("date", ascending);
queryBuilder.limit(count + 1);
preparedQuery = queryBuilder.prepare();
profileSwitches = daoProfileSwitch.query(preparedQuery); profileSwitches = daoProfileSwitch.query(preparedQuery);
//add last one without duration
ProfileSwitch last = getLastProfileSwitchWithoutDuration();
if (last != null) {
if (!profileSwitches.contains(last))
profileSwitches.add(last);
}
return profileSwitches; return profileSwitches;
} catch (SQLException e) { } catch (SQLException e) {
log.error("Unhandled exception", e); log.error("Unhandled exception", e);
@ -1618,6 +1608,28 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
return new ArrayList<>(); return new ArrayList<>();
} }
@Nullable
private ProfileSwitch getLastProfileSwitchWithoutDuration() {
try {
Dao<ProfileSwitch, Long> daoProfileSwitch = getDaoProfileSwitch();
List<ProfileSwitch> profileSwitches;
QueryBuilder<ProfileSwitch, Long> queryBuilder = daoProfileSwitch.queryBuilder();
queryBuilder.orderBy("date", false);
queryBuilder.limit(1L);
Where where = queryBuilder.where();
where.eq("durationInMinutes", 0);
PreparedQuery<ProfileSwitch> preparedQuery = queryBuilder.prepare();
profileSwitches = daoProfileSwitch.query(preparedQuery);
if (profileSwitches.size() > 0)
return profileSwitches.get(0);
else
return null;
} catch (SQLException e) {
log.error("Unhandled exception", e);
}
return null;
}
public List<ProfileSwitch> getProfileSwitchEventsFromTime(long mills, boolean ascending) { public List<ProfileSwitch> getProfileSwitchEventsFromTime(long mills, boolean ascending) {
try { try {
Dao<ProfileSwitch, Long> daoProfileSwitch = getDaoProfileSwitch(); Dao<ProfileSwitch, Long> daoProfileSwitch = getDaoProfileSwitch();

View file

@ -11,6 +11,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.utils.DateUtil;
/** /**
* Created by mike on 27.02.2016. * Created by mike on 27.02.2016.
@ -40,34 +41,47 @@ public class DbRequest {
} }
// dbAdd // dbAdd
public DbRequest(String action, String collection, String nsClientID, JSONObject data) { public DbRequest(String action, String collection, JSONObject data) {
this.action = action; this.action = action;
this.collection = collection; this.collection = collection;
this.nsClientID = "" + DateUtil.now();
try {
data.put("NSCLIENT_ID", nsClientID);
} catch (JSONException e) {
e.printStackTrace();
}
this.data = data.toString(); this.data = data.toString();
this.nsClientID = nsClientID;
this._id = ""; this._id = "";
} }
// dbUpdate, dbUpdateUnset // dbUpdate, dbUpdateUnset
public DbRequest(String action, String collection, String nsClientID, String _id, JSONObject data) { public DbRequest(String action, String collection, String _id, JSONObject data) {
this.action = action; this.action = action;
this.collection = collection; this.collection = collection;
this.nsClientID = "" + DateUtil.now();
try {
data.put("NSCLIENT_ID", nsClientID);
} catch (JSONException e) {
e.printStackTrace();
}
this.data = data.toString(); this.data = data.toString();
this.nsClientID = nsClientID;
this._id = _id; this._id = _id;
} }
// dbRemove // dbRemove
public DbRequest(String action, String collection, String nsClientID, String _id) { public DbRequest(String action, String collection,
String _id) {
JSONObject data = new JSONObject();
this.action = action; this.action = action;
this.collection = collection; this.collection = collection;
this.data = new JSONObject().toString(); this.nsClientID = "" + DateUtil.now();
this.nsClientID = nsClientID; try {
this._id = _id; data.put("NSCLIENT_ID", nsClientID);
} catch (JSONException e) {
e.printStackTrace();
} }
this.data = data.toString();
public String hash() { this._id = _id;
return Hashing.sha1().hashString(action + collection + _id + data.toString(), Charsets.UTF_8).toString();
} }
public JSONObject toJSON() { public JSONObject toJSON() {

View file

@ -1,11 +1,13 @@
package info.nightscout.androidaps.dependencyInjection package info.nightscout.androidaps.dependencyInjection
import android.app.Application
import dagger.BindsInstance import dagger.BindsInstance
import dagger.Component import dagger.Component
import dagger.android.AndroidInjectionModule import dagger.android.AndroidInjectionModule
import dagger.android.AndroidInjector import dagger.android.AndroidInjector
import info.nightscout.androidaps.MainApp import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.plugins.general.automation.actions.ActionSendSMS
import info.nightscout.androidaps.queue.commands.CommandSetProfile
import info.nightscout.androidaps.services.DataService
import javax.inject.Singleton import javax.inject.Singleton
@Singleton @Singleton
@ -19,11 +21,17 @@ import javax.inject.Singleton
) )
interface AppComponent : AndroidInjector<MainApp> { interface AppComponent : AndroidInjector<MainApp> {
fun injectDataService(service: DataService)
fun injectCommandSetProfile(commandSetProfile: CommandSetProfile)
fun injectActionSendSMS(actionSendSMS: ActionSendSMS)
@Component.Builder @Component.Builder
interface Builder { interface Builder {
@BindsInstance @BindsInstance
fun application(application: Application): Builder fun application(mainApp: MainApp): Builder
fun build(): AppComponent fun build(): AppComponent
} }

View file

@ -1,13 +1,21 @@
package info.nightscout.androidaps.dependencyInjection package info.nightscout.androidaps.dependencyInjection
import android.app.Application
import android.content.Context import android.content.Context
import android.preference.PreferenceManager import android.preference.PreferenceManager
import dagger.Binds import dagger.Binds
import dagger.Module import dagger.Module
import dagger.Provides import dagger.Provides
import dagger.android.ContributesAndroidInjector
import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunction
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctionImplementation
import info.nightscout.androidaps.plugins.general.automation.actions.ActionSendSMS
import info.nightscout.androidaps.queue.commands.CommandSetProfile
import info.nightscout.androidaps.services.DataService
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.resources.ResourceHelperImplementation
import info.nightscout.androidaps.utils.sharedPreferences.SP import info.nightscout.androidaps.utils.sharedPreferences.SP
import info.nightscout.androidaps.utils.sharedPreferences.SPImpl import info.nightscout.androidaps.utils.sharedPreferences.SPImplementation
import javax.inject.Singleton import javax.inject.Singleton
@Module(includes = [AppModule.AppBindings::class]) @Module(includes = [AppModule.AppBindings::class])
@ -16,13 +24,34 @@ class AppModule {
@Provides @Provides
@Singleton @Singleton
fun provideSharedPreferences(context: Context): SP { fun provideSharedPreferences(context: Context): SP {
return SPImpl(PreferenceManager.getDefaultSharedPreferences(context)) return SPImplementation(PreferenceManager.getDefaultSharedPreferences(context))
}
@Provides
@Singleton
fun provideProfileFunction(sp: SP): ProfileFunction {
return ProfileFunctionImplementation(sp)
}
@Provides
@Singleton
fun provideResources(mainApp: MainApp): ResourceHelper {
return ResourceHelperImplementation(mainApp)
} }
@Module @Module
interface AppBindings { interface AppBindings {
@ContributesAndroidInjector
fun bindDataService(): DataService
@ContributesAndroidInjector
fun bindCommandSetProfile(): CommandSetProfile
@ContributesAndroidInjector
fun bindActionSendSMS(): ActionSendSMS
@Binds @Binds
fun bindContext(application: Application): Context fun bindContext(mainApp: MainApp): Context
} }
} }

View file

@ -3,9 +3,13 @@ package info.nightscout.androidaps.dependencyInjection
import dagger.Module import dagger.Module
import dagger.android.ContributesAndroidInjector import dagger.android.ContributesAndroidInjector
import info.nightscout.androidaps.activities.MyPreferenceFragment import info.nightscout.androidaps.activities.MyPreferenceFragment
import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorFragment
@Module @Module
abstract class FragmentsModule { abstract class FragmentsModule {
@ContributesAndroidInjector @ContributesAndroidInjector
abstract fun contributesPreferencesFragment(): MyPreferenceFragment abstract fun contributesPreferencesFragment(): MyPreferenceFragment
@ContributesAndroidInjector
abstract fun contributesSmsCommunicatorFragment(): SmsCommunicatorFragment
} }

View file

@ -0,0 +1,159 @@
package info.nightscout.androidaps.dialogs
import android.app.Activity
import android.os.Bundle
import android.os.SystemClock
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.Window
import android.view.WindowManager
import androidx.fragment.app.DialogFragment
import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R
import info.nightscout.androidaps.activities.BolusProgressHelperActivity
import info.nightscout.androidaps.events.EventPumpStatusChanged
import info.nightscout.androidaps.logging.L
import info.nightscout.androidaps.plugins.bus.RxBus.toObservable
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin
import info.nightscout.androidaps.plugins.general.overview.events.EventDismissBolusProgressIfRunning
import info.nightscout.androidaps.plugins.general.overview.events.EventOverviewBolusProgress
import info.nightscout.androidaps.utils.FabricPrivacy
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import kotlinx.android.synthetic.main.dialog_bolusprogress.*
import org.slf4j.LoggerFactory
class BolusProgressDialog : DialogFragment() {
private val log = LoggerFactory.getLogger(L.UI)
private val disposable = CompositeDisposable()
companion object {
private val DEFAULT_STATE = MainApp.gs(R.string.waitingforpump)
@JvmField
var bolusEnded = false
@JvmField
var stopPressed = false
}
private var running = true
private var amount = 0.0
private var state: String? = null
private var helpActivity: BolusProgressHelperActivity? = null
fun setInsulin(amount: Double): BolusProgressDialog {
this.amount = amount
bolusEnded = false
return this
}
fun setHelperActivity(activity: BolusProgressHelperActivity): BolusProgressDialog {
helpActivity = activity
return this
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
dialog?.window?.requestFeature(Window.FEATURE_NO_TITLE)
dialog?.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN)
isCancelable = true
dialog?.setCanceledOnTouchOutside(false)
return inflater.inflate(R.layout.dialog_bolusprogress, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
overview_bolusprogress_title.text = String.format(MainApp.gs(R.string.overview_bolusprogress_goingtodeliver), amount)
overview_bolusprogress_stop.setOnClickListener {
if (L.isEnabled(L.UI)) log.debug("Stop bolus delivery button pressed")
stopPressed = true
overview_bolusprogress_stoppressed.visibility = View.VISIBLE
overview_bolusprogress_stop.visibility = View.INVISIBLE
ConfigBuilderPlugin.getPlugin().commandQueue.cancelAllBoluses()
}
overview_bolusprogress_progressbar.max = 100
state = savedInstanceState?.getString("state", DEFAULT_STATE) ?: DEFAULT_STATE
overview_bolusprogress_status.text = state
stopPressed = false
}
override fun onStart() {
super.onStart()
dialog?.window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
}
override fun onResume() {
super.onResume()
if (L.isEnabled(L.UI)) log.debug("onResume")
if (!ConfigBuilderPlugin.getPlugin().commandQueue.bolusInQueue())
bolusEnded = true
if (bolusEnded) dismiss()
else running = true
disposable.add(toObservable(EventPumpStatusChanged::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ overview_bolusprogress_status.text = it.getStatus() }) { FabricPrivacy.logException(it) }
)
disposable.add(toObservable(EventDismissBolusProgressIfRunning::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ if (running) dismiss() }) { FabricPrivacy.logException(it) }
)
disposable.add(toObservable(EventOverviewBolusProgress::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
if (L.isEnabled(L.UI)) log.debug("Status: " + it.status + " Percent: " + it.percent)
overview_bolusprogress_status.text = it.status
overview_bolusprogress_progressbar.progress = it.percent
if (it.percent == 100) {
overview_bolusprogress_stop.visibility = View.INVISIBLE
scheduleDismiss()
}
state = it.status
}) { FabricPrivacy.logException(it) }
)
}
override fun dismiss() {
if (L.isEnabled(L.UI)) log.debug("dismiss")
try {
super.dismiss()
} catch (e: IllegalStateException) {
// dialog not running yet. onResume will try again. Set bolusEnded to make extra
// sure onResume will catch this
bolusEnded = true
log.error("Unhandled exception", e)
}
helpActivity?.finish()
}
override fun onPause() {
super.onPause()
if (L.isEnabled(L.UI)) log.debug("onPause")
running = false
disposable.clear()
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putString("state", state)
}
private fun scheduleDismiss() {
if (L.isEnabled(L.UI)) log.debug("scheduleDismiss")
Thread(Runnable {
SystemClock.sleep(5000)
bolusEnded = true
val activity: Activity? = activity
activity?.runOnUiThread {
if (running) {
if (L.isEnabled(L.UI)) log.debug("executing")
try {
dismiss()
} catch (e: Exception) {
log.error("Unhandled exception", e)
}
}
}
}).start()
}
}

View file

@ -0,0 +1,68 @@
package info.nightscout.androidaps.dialogs
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.google.common.base.Joiner
import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus
import info.nightscout.androidaps.utils.HtmlHelper
import info.nightscout.androidaps.utils.OKDialog
import info.nightscout.androidaps.utils.XdripCalibrations
import kotlinx.android.synthetic.main.dialog_calibration.*
import kotlinx.android.synthetic.main.okcancel.*
import java.text.DecimalFormat
import java.util.*
class CalibrationDialog : DialogFragmentWithDate() {
override fun onSaveInstanceState(savedInstanceState: Bundle) {
super.onSaveInstanceState(savedInstanceState)
savedInstanceState.putDouble("overview_calibration_bg", overview_calibration_bg.value)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
onCreateViewGeneral()
return inflater.inflate(R.layout.dialog_calibration, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val units = ProfileFunctions.getSystemUnits()
val bg = Profile.fromMgdlToUnits(GlucoseStatus.getGlucoseStatusData()?.glucose
?: 0.0, units)
if (units == Constants.MMOL)
overview_calibration_bg.setParams(savedInstanceState?.getDouble("overview_calibration_bg")
?: bg, 2.0, 30.0, 0.1, DecimalFormat("0.0"), false, ok)
else
overview_calibration_bg.setParams(savedInstanceState?.getDouble("overview_calibration_bg")
?: bg, 36.0, 500.0, 1.0, DecimalFormat("0"), false, ok)
overview_calibration_units.text = if (units == Constants.MMOL) MainApp.gs(R.string.mmol) else MainApp.gs(R.string.mgdl)
}
override fun submit() :Boolean {
val units = ProfileFunctions.getSystemUnits()
val unitLabel = if (units == Constants.MMOL) MainApp.gs(R.string.mmol) else MainApp.gs(R.string.mgdl)
val actions: LinkedList<String?> = LinkedList()
val bg = overview_calibration_bg.value
actions.add(MainApp.gs(R.string.treatments_wizard_bg_label) + ": " + Profile.toCurrentUnitsString(bg) + " " + unitLabel)
if (bg > 0) {
activity?.let { activity ->
OKDialog.showConfirmation(activity, MainApp.gs(R.string.overview_calibration), HtmlHelper.fromHtml(Joiner.on("<br/>").join(actions)), Runnable {
XdripCalibrations.confirmAndSendCalibration(bg, context)
})
}
} else
activity?.let { activity ->
OKDialog.show(activity, MainApp.gs(R.string.overview_calibration), MainApp.gs(R.string.no_action_selected))
}
return true
}
}

View file

@ -0,0 +1,220 @@
package info.nightscout.androidaps.dialogs
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.google.common.base.Joiner
import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.db.CareportalEvent
import info.nightscout.androidaps.db.DatabaseHelper
import info.nightscout.androidaps.db.Source
import info.nightscout.androidaps.db.TempTarget
import info.nightscout.androidaps.interfaces.Constraint
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload
import info.nightscout.androidaps.plugins.treatments.CarbsGenerator
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
import info.nightscout.androidaps.utils.*
import kotlinx.android.synthetic.main.dialog_carbs.*
import kotlinx.android.synthetic.main.notes.*
import kotlinx.android.synthetic.main.okcancel.*
import java.text.DecimalFormat
import java.util.*
import kotlin.math.max
class CarbsDialog : DialogFragmentWithDate() {
companion object {
private const val FAV1_DEFAULT = 5
private const val FAV2_DEFAULT = 10
private const val FAV3_DEFAULT = 20
}
private val maxCarbs = MainApp.getConstraintChecker().maxCarbsAllowed.value().toDouble()
private val textWatcher: TextWatcher = object : TextWatcher {
override fun afterTextChanged(s: Editable) {
validateInputs()
}
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {}
}
private fun validateInputs() {
val time = overview_carbs_time.value.toInt()
if (time > 12 * 60 || time < -12 * 60) {
overview_carbs_time.value = 0.0
ToastUtils.showToastInUiThread(MainApp.instance().applicationContext, MainApp.gs(R.string.constraintapllied))
}
if (overview_carbs_duration.value > 10) {
overview_carbs_duration.value = 0.0
ToastUtils.showToastInUiThread(MainApp.instance().applicationContext, MainApp.gs(R.string.constraintapllied))
}
if (overview_carbs_carbs.value.toInt() > maxCarbs) {
overview_carbs_carbs.value = 0.0
ToastUtils.showToastInUiThread(MainApp.instance().applicationContext, MainApp.gs(R.string.carbsconstraintapplied))
}
}
override fun onSaveInstanceState(savedInstanceState: Bundle) {
super.onSaveInstanceState(savedInstanceState)
savedInstanceState.putDouble("overview_carbs_time", overview_carbs_time.value)
savedInstanceState.putDouble("overview_carbs_duration", overview_carbs_duration.value)
savedInstanceState.putDouble("overview_carbs_carbs", overview_carbs_carbs.value)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
onCreateViewGeneral()
return inflater.inflate(R.layout.dialog_carbs, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
overview_carbs_time.setParams(savedInstanceState?.getDouble("overview_carbs_time")
?: 0.0, -12 * 60.0, 12 * 60.0, 5.0, DecimalFormat("0"), false, ok, textWatcher)
overview_carbs_duration.setParams(savedInstanceState?.getDouble("overview_carbs_duration")
?: 0.0, 0.0, 10.0, 1.0, DecimalFormat("0"), false, ok, textWatcher)
overview_carbs_carbs.setParams(savedInstanceState?.getDouble("overview_carbs_carbs")
?: 0.0, 0.0, maxCarbs, 1.0, DecimalFormat("0"), false, ok, textWatcher)
overview_carbs_plus1.text = toSignedString(SP.getInt(R.string.key_carbs_button_increment_1, FAV1_DEFAULT))
overview_carbs_plus1.setOnClickListener {
overview_carbs_carbs.value = max(0.0, overview_carbs_carbs.value
+ SP.getInt(R.string.key_carbs_button_increment_1, FAV1_DEFAULT))
validateInputs()
}
overview_carbs_plus2.text = toSignedString(SP.getInt(R.string.key_carbs_button_increment_2, FAV2_DEFAULT))
overview_carbs_plus2.setOnClickListener {
overview_carbs_carbs.value = max(0.0, overview_carbs_carbs.value
+ SP.getInt(R.string.key_carbs_button_increment_2, FAV2_DEFAULT))
validateInputs()
}
overview_carbs_plus3.text = toSignedString(SP.getInt(R.string.key_carbs_button_increment_3, FAV3_DEFAULT))
overview_carbs_plus3.setOnClickListener {
overview_carbs_carbs.value = max(0.0, overview_carbs_carbs.value
+ SP.getInt(R.string.key_carbs_button_increment_3, FAV3_DEFAULT))
validateInputs()
}
DatabaseHelper.actualBg()?.let { bgReading ->
if (bgReading.value < 72)
overview_carbs_hypo_tt.setChecked(true)
}
overview_carbs_hypo_tt.setOnClickListener {
overview_carbs_activity_tt.isChecked = false
overview_carbs_eating_soon_tt.isChecked = false
}
overview_carbs_activity_tt.setOnClickListener {
overview_carbs_hypo_tt.isChecked = false
overview_carbs_eating_soon_tt.isChecked = false
}
overview_carbs_eating_soon_tt.setOnClickListener {
overview_carbs_hypo_tt.isChecked = false
overview_carbs_activity_tt.isChecked = false
}
}
private fun toSignedString(value: Int): String {
return if (value > 0) "+$value" else value.toString()
}
override fun submit(): Boolean {
val carbs = overview_carbs_carbs.value.toInt()
val carbsAfterConstraints = MainApp.getConstraintChecker().applyCarbsConstraints(Constraint(carbs)).value()
val units = ProfileFunctions.getSystemUnits()
val activityTTDuration = DefaultValueHelper.determineActivityTTDuration()
val activityTT = DefaultValueHelper.determineActivityTT()
val eatingSoonTTDuration = DefaultValueHelper.determineEatingSoonTTDuration()
val eatingSoonTT = DefaultValueHelper.determineEatingSoonTT()
val hypoTTDuration = DefaultValueHelper.determineHypoTTDuration()
val hypoTT = DefaultValueHelper.determineHypoTT()
val actions: LinkedList<String?> = LinkedList()
val unitLabel = if (units == Constants.MMOL) MainApp.gs(R.string.mmol) else MainApp.gs(R.string.mgdl)
val activitySelected = overview_carbs_activity_tt.isChecked
if (activitySelected)
actions.add(MainApp.gs(R.string.temptargetshort) + ": " + "<font color='" + MainApp.gc(R.color.tempTargetConfirmation) + "'>" + DecimalFormatter.to1Decimal(activityTT) + " " + unitLabel + " (" + activityTTDuration + " " + MainApp.gs(R.string.unit_minute_short) + ")</font>")
val eatingSoonSelected = overview_carbs_eating_soon_tt.isChecked
if (eatingSoonSelected)
actions.add(MainApp.gs(R.string.temptargetshort) + ": " + "<font color='" + MainApp.gc(R.color.tempTargetConfirmation) + "'>" + DecimalFormatter.to1Decimal(eatingSoonTT) + " " + unitLabel + " (" + eatingSoonTTDuration + " " + MainApp.gs(R.string.unit_minute_short) + ")</font>")
val hypoSelected = overview_carbs_hypo_tt.isChecked
if (hypoSelected)
actions.add(MainApp.gs(R.string.temptargetshort) + ": " + "<font color='" + MainApp.gc(R.color.tempTargetConfirmation) + "'>" + DecimalFormatter.to1Decimal(hypoTT) + " " + unitLabel + " (" + hypoTTDuration + " " + MainApp.gs(R.string.unit_minute_short) + ")</font>")
val timeOffset = overview_carbs_time.value.toInt()
val time = DateUtil.now() + timeOffset * 1000 * 60
if (timeOffset != 0)
actions.add(MainApp.gs(R.string.time) + ": " + DateUtil.dateAndTimeString(time))
val duration = overview_carbs_duration.value.toInt()
if (duration > 0)
actions.add(MainApp.gs(R.string.duration) + ": " + duration + MainApp.gs(R.string.shorthour))
if (carbsAfterConstraints > 0) {
actions.add(MainApp.gs(R.string.carbs) + ": " + "<font color='" + MainApp.gc(R.color.carbs) + "'>" + MainApp.gs(R.string.format_carbs, carbsAfterConstraints) + "</font>")
if (carbsAfterConstraints != carbs)
actions.add("<font color='" + MainApp.gc(R.color.warning) + "'>" + MainApp.gs(R.string.carbsconstraintapplied) + "</font>")
}
val notes = notes.text.toString()
if (notes.isNotEmpty())
actions.add(MainApp.gs(R.string.careportal_newnstreatment_notes_label) + ": " + notes)
if (carbsAfterConstraints > 0 || activitySelected || eatingSoonSelected || hypoSelected) {
activity?.let { activity ->
OKDialog.showConfirmation(activity, MainApp.gs(R.string.carbs), HtmlHelper.fromHtml(Joiner.on("<br/>").join(actions)), Runnable {
if (activitySelected) {
val tempTarget = TempTarget()
.date(System.currentTimeMillis())
.duration(activityTTDuration)
.reason(MainApp.gs(R.string.activity))
.source(Source.USER)
.low(Profile.toMgdl(activityTT, ProfileFunctions.getSystemUnits()))
.high(Profile.toMgdl(activityTT, ProfileFunctions.getSystemUnits()))
TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget)
} else if (eatingSoonSelected) {
val tempTarget = TempTarget()
.date(System.currentTimeMillis())
.duration(eatingSoonTTDuration)
.reason(MainApp.gs(R.string.eatingsoon))
.source(Source.USER)
.low(Profile.toMgdl(eatingSoonTT, ProfileFunctions.getSystemUnits()))
.high(Profile.toMgdl(eatingSoonTT, ProfileFunctions.getSystemUnits()))
TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget)
} else if (hypoSelected) {
val tempTarget = TempTarget()
.date(System.currentTimeMillis())
.duration(hypoTTDuration)
.reason(MainApp.gs(R.string.hypo))
.source(Source.USER)
.low(Profile.toMgdl(hypoTT, ProfileFunctions.getSystemUnits()))
.high(Profile.toMgdl(hypoTT, ProfileFunctions.getSystemUnits()))
TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget)
}
if (carbsAfterConstraints > 0) {
if (duration == 0) {
CarbsGenerator.createCarb(carbsAfterConstraints, time, CareportalEvent.CARBCORRECTION, notes)
} else {
CarbsGenerator.generateCarbs(carbsAfterConstraints, time, duration, notes)
NSUpload.uploadEvent(CareportalEvent.NOTE, DateUtil.now() - 2000, MainApp.gs(R.string.generated_ecarbs_note, carbsAfterConstraints, duration, timeOffset))
}
}
}, null)
}
} else
activity?.let { activity ->
OKDialog.show(activity, MainApp.gs(R.string.carbs), MainApp.gs(R.string.no_action_selected))
}
return true
}
}

View file

@ -0,0 +1,150 @@
package info.nightscout.androidaps.dialogs
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.annotation.StringRes
import com.google.common.base.Joiner
import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.db.CareportalEvent
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.HtmlHelper
import info.nightscout.androidaps.utils.OKDialog
import info.nightscout.androidaps.utils.SP
import info.nightscout.androidaps.utils.Translator
import kotlinx.android.synthetic.main.dialog_care.*
import kotlinx.android.synthetic.main.notes.*
import kotlinx.android.synthetic.main.okcancel.*
import org.json.JSONObject
import java.text.DecimalFormat
import java.util.*
class CareDialog : DialogFragmentWithDate() {
enum class EventType {
BGCHECK,
SENSOR_INSERT,
BATTERY_CHANGE
}
private var options: EventType = EventType.BGCHECK
@StringRes
private var event: Int = R.string.none
fun setOptions(options: EventType, @StringRes event: Int): CareDialog {
this.options = options
this.event = event
return this
}
override fun onSaveInstanceState(savedInstanceState: Bundle) {
super.onSaveInstanceState(savedInstanceState)
savedInstanceState.putDouble("actions_care_bg", actions_care_bg.value)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
onCreateViewGeneral()
return inflater.inflate(R.layout.dialog_care, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
actions_care_icon.setImageResource(when (options) {
EventType.BGCHECK -> R.drawable.icon_cp_bgcheck
EventType.SENSOR_INSERT -> R.drawable.icon_cp_cgm_insert
EventType.BATTERY_CHANGE -> R.drawable.icon_cp_pump_battery
})
actions_care_title.text = MainApp.gs(when (options) {
EventType.BGCHECK -> R.string.careportal_bgcheck
EventType.SENSOR_INSERT -> R.string.careportal_cgmsensorinsert
EventType.BATTERY_CHANGE -> R.string.careportal_pumpbatterychange
})
when (options) {
EventType.SENSOR_INSERT,
EventType.BATTERY_CHANGE -> {
action_care_bg_layout.visibility = View.GONE
actions_care_bgsource.visibility = View.GONE
}
else -> {
}
}
val bg = Profile.fromMgdlToUnits(GlucoseStatus.getGlucoseStatusData()?.glucose
?: 0.0, ProfileFunctions.getSystemUnits())
val bgTextWatcher: TextWatcher = object : TextWatcher {
override fun afterTextChanged(s: Editable) {}
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
if (actions_care_sensor.isChecked) actions_care_meter.isChecked = true
}
}
if (ProfileFunctions.getSystemUnits() == Constants.MMOL) {
actions_care_bgunits.text = MainApp.gs(R.string.mmol)
actions_care_bg.setParams(savedInstanceState?.getDouble("actions_care_bg")
?: bg, 2.0, 30.0, 0.1, DecimalFormat("0.0"), false, ok, bgTextWatcher)
} else {
actions_care_bgunits.text = MainApp.gs(R.string.mgdl)
actions_care_bg.setParams(savedInstanceState?.getDouble("actions_care_bg")
?: bg, 36.0, 500.0, 1.0, DecimalFormat("0"), false, ok, bgTextWatcher)
}
}
override fun submit(): Boolean {
val enteredBy = SP.getString("careportal_enteredby", "")
val unitResId = if (ProfileFunctions.getSystemUnits() == Constants.MGDL) R.string.mgdl else R.string.mmol
val json = JSONObject()
val actions: LinkedList<String> = LinkedList()
if (options == EventType.BGCHECK) {
val type =
when {
actions_care_meter.isChecked -> "Finger"
actions_care_sensor.isChecked -> "Sensor"
else -> "Manual"
}
actions.add(MainApp.gs(R.string.careportal_newnstreatment_glucosetype) + ": " + Translator.translate(type))
actions.add(MainApp.gs(R.string.treatments_wizard_bg_label) + ": " + Profile.toCurrentUnitsString(actions_care_bg.value) + " " + MainApp.gs(unitResId))
json.put("glucose", actions_care_bg.value)
json.put("glucoseType", type)
}
val notes = notes.text.toString()
if (notes.isNotEmpty()) {
actions.add(MainApp.gs(R.string.careportal_newnstreatment_notes_label) + ": " + notes)
json.put("notes", notes)
}
if (eventTimeChanged)
actions.add(MainApp.gs(R.string.time) + ": " + DateUtil.dateAndTimeString(eventTime))
json.put("created_at", DateUtil.toISOString(eventTime))
json.put("eventType", when (options) {
EventType.BGCHECK -> CareportalEvent.BGCHECK
EventType.SENSOR_INSERT -> CareportalEvent.SENSORCHANGE
EventType.BATTERY_CHANGE -> CareportalEvent.PUMPBATTERYCHANGE
})
json.put("units", ProfileFunctions.getSystemUnits())
if (enteredBy.isNotEmpty())
json.put("enteredBy", enteredBy)
activity?.let { activity ->
OKDialog.showConfirmation(activity, MainApp.gs(event), HtmlHelper.fromHtml(Joiner.on("<br/>").join(actions)), Runnable {
MainApp.getDbHelper().createCareportalEventFromJsonIfNotExists(json)
NSUpload.uploadCareportalEntryToNS(json)
}, null)
}
return true
}
}

View file

@ -0,0 +1,124 @@
package info.nightscout.androidaps.dialogs
import android.app.DatePickerDialog
import android.app.TimePickerDialog
import android.os.Bundle
import android.text.format.DateFormat
import android.view.View
import android.view.ViewGroup
import android.view.Window
import android.view.WindowManager
import androidx.fragment.app.DialogFragment
import info.nightscout.androidaps.R
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.SP
import info.nightscout.androidaps.utils.toVisibility
import kotlinx.android.synthetic.main.datetime.*
import kotlinx.android.synthetic.main.notes.*
import kotlinx.android.synthetic.main.okcancel.*
import org.slf4j.LoggerFactory
import java.util.*
abstract class DialogFragmentWithDate : DialogFragment() {
private val log = LoggerFactory.getLogger(DialogFragmentWithDate::class.java)
var eventTime = DateUtil.now()
var eventTimeChanged = false
//one shot guards
private var okClicked: Boolean = false
companion object {
private var seconds: Int = (Math.random() * 59.0).toInt()
}
override fun onStart() {
super.onStart()
dialog?.window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
}
override fun onSaveInstanceState(savedInstanceState: Bundle) {
super.onSaveInstanceState(savedInstanceState)
savedInstanceState.putLong("eventTime", eventTime)
savedInstanceState.putBoolean("eventTimeChanged", eventTimeChanged)
}
fun onCreateViewGeneral() {
dialog?.window?.requestFeature(Window.FEATURE_NO_TITLE)
dialog?.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN)
isCancelable = true
dialog?.setCanceledOnTouchOutside(false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
eventTime = savedInstanceState?.getLong("eventTime") ?: DateUtil.now()
eventTimeChanged = savedInstanceState?.getBoolean("eventTimeChanged") ?: false
overview_eventdate?.text = DateUtil.dateString(eventTime)
overview_eventtime?.text = DateUtil.timeString(eventTime)
// create an OnDateSetListener
val dateSetListener = DatePickerDialog.OnDateSetListener { _, year, monthOfYear, dayOfMonth ->
val cal = Calendar.getInstance()
cal.timeInMillis = eventTime
cal.set(Calendar.YEAR, year)
cal.set(Calendar.MONTH, monthOfYear)
cal.set(Calendar.DAY_OF_MONTH, dayOfMonth)
eventTime = cal.timeInMillis
eventTimeChanged = true
overview_eventdate?.text = DateUtil.dateString(eventTime)
}
overview_eventdate?.setOnClickListener {
context?.let {
val cal = Calendar.getInstance()
cal.timeInMillis = eventTime
DatePickerDialog(it, dateSetListener,
cal.get(Calendar.YEAR),
cal.get(Calendar.MONTH),
cal.get(Calendar.DAY_OF_MONTH)
).show()
}
}
// create an OnTimeSetListener
val timeSetListener = TimePickerDialog.OnTimeSetListener { _, hour, minute ->
val cal = Calendar.getInstance()
cal.timeInMillis = eventTime
cal.set(Calendar.HOUR_OF_DAY, hour)
cal.set(Calendar.MINUTE, minute)
cal.set(Calendar.SECOND, seconds++) // randomize seconds to prevent creating record of the same time, if user choose time manually
eventTime = cal.timeInMillis
eventTimeChanged = true
overview_eventtime?.text = DateUtil.timeString(eventTime)
}
overview_eventtime?.setOnClickListener {
context?.let {
val cal = Calendar.getInstance()
cal.timeInMillis = eventTime
TimePickerDialog(it, timeSetListener,
cal.get(Calendar.HOUR_OF_DAY),
cal.get(Calendar.MINUTE),
DateFormat.is24HourFormat(context)
).show()
}
}
notes_layout?.visibility = SP.getBoolean(R.string.key_show_notes_entry_dialogs, false).toVisibility()
ok.setOnClickListener {
synchronized(okClicked) {
if (okClicked) {
log.debug("guarding: ok already clicked")
} else {
okClicked = true
if (submit()) dismiss()
else okClicked = false
}
}
}
cancel.setOnClickListener { dismiss() }
}
abstract fun submit(): Boolean
}

View file

@ -1,5 +1,4 @@
package info.nightscout.androidaps.plugins.general.overview.dialogs package info.nightscout.androidaps.dialogs
import android.content.Intent import android.content.Intent
import android.os.Build import android.os.Build
@ -7,11 +6,14 @@ import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.view.Window
import android.view.WindowManager
import androidx.fragment.app.DialogFragment import androidx.fragment.app.DialogFragment
import info.nightscout.androidaps.MainApp import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R import info.nightscout.androidaps.R
import info.nightscout.androidaps.activities.ErrorHelperActivity
import info.nightscout.androidaps.services.AlarmSoundService import info.nightscout.androidaps.services.AlarmSoundService
import kotlinx.android.synthetic.main.overview_error_dialog.* import kotlinx.android.synthetic.main.dialog_error.*
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory
class ErrorDialog : DialogFragment() { class ErrorDialog : DialogFragment() {
@ -24,20 +26,23 @@ class ErrorDialog : DialogFragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? { savedInstanceState: Bundle?): View? {
dialog?.setTitle(title) dialog?.window?.requestFeature(Window.FEATURE_NO_TITLE)
isCancelable = false dialog?.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN)
isCancelable = true
dialog?.setCanceledOnTouchOutside(false)
savedInstanceState?.let { bundle -> savedInstanceState?.let { bundle ->
bundle.getString("status")?.let { status = it } bundle.getString("status")?.let { status = it }
bundle.getString("title")?.let { title = it } bundle.getString("title")?.let { title = it }
sound = bundle.getInt("sound", R.raw.error) sound = bundle.getInt("sound", R.raw.error)
} }
return inflater.inflate(R.layout.overview_error_dialog, container, false) return inflater.inflate(R.layout.dialog_error, container, false)
} }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
error_title.text = title
overview_error_ok.setOnClickListener { overview_error_ok.setOnClickListener {
log.debug("Error dialog ok button pressed") log.debug("Error dialog ok button pressed")
dismiss() dismiss()
@ -56,9 +61,13 @@ class ErrorDialog : DialogFragment() {
bundle.putInt("sound", sound) bundle.putInt("sound", sound)
} }
override fun onStart() {
super.onStart()
dialog?.window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
}
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
dialog?.window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
overview_error_status.text = status overview_error_status.text = status
} }

View file

@ -0,0 +1,82 @@
package info.nightscout.androidaps.dialogs
import android.content.Intent
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.google.common.base.Joiner
import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R
import info.nightscout.androidaps.activities.ErrorHelperActivity
import info.nightscout.androidaps.interfaces.Constraint
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin
import info.nightscout.androidaps.queue.Callback
import info.nightscout.androidaps.utils.HtmlHelper
import info.nightscout.androidaps.utils.OKDialog
import info.nightscout.androidaps.utils.SafeParse
import kotlinx.android.synthetic.main.dialog_extendedbolus.*
import kotlinx.android.synthetic.main.okcancel.*
import java.text.DecimalFormat
import java.util.*
import kotlin.math.abs
class ExtendedBolusDialog : DialogFragmentWithDate() {
override fun onSaveInstanceState(savedInstanceState: Bundle) {
super.onSaveInstanceState(savedInstanceState)
savedInstanceState.putDouble("actions_extendedbolus_insulin", actions_extendedbolus_insulin.value)
savedInstanceState.putDouble("actions_extendedbolus_duration", actions_extendedbolus_duration.value)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
onCreateViewGeneral()
return inflater.inflate(R.layout.dialog_extendedbolus, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val pumpDescription = ConfigBuilderPlugin.getPlugin().activePump?.pumpDescription ?: return
val maxInsulin = MainApp.getConstraintChecker().maxExtendedBolusAllowed.value()
val extendedStep = pumpDescription.extendedBolusStep
actions_extendedbolus_insulin.setParams(savedInstanceState?.getDouble("actions_extendedbolus_insulin")
?: extendedStep, extendedStep, maxInsulin, extendedStep, DecimalFormat("0.00"), false, ok)
val extendedDurationStep = pumpDescription.extendedBolusDurationStep
val extendedMaxDuration = pumpDescription.extendedBolusMaxDuration
actions_extendedbolus_duration.setParams(savedInstanceState?.getDouble("actions_extendedbolus_duration")
?: extendedDurationStep, extendedDurationStep, extendedMaxDuration, extendedDurationStep, DecimalFormat("0"), false, ok)
}
override fun submit(): Boolean {
val insulin = SafeParse.stringToDouble(actions_extendedbolus_insulin.text)
val durationInMinutes = SafeParse.stringToInt(actions_extendedbolus_duration.text)
val actions: LinkedList<String> = LinkedList()
val insulinAfterConstraint = MainApp.getConstraintChecker().applyExtendedBolusConstraints(Constraint(insulin)).value()
actions.add(MainApp.gs(R.string.formatinsulinunits, insulinAfterConstraint))
actions.add(MainApp.gs(R.string.duration) + ": " + MainApp.gs(R.string.format_mins, durationInMinutes))
if (abs(insulinAfterConstraint - insulin) > 0.01)
actions.add("<font color='" + MainApp.gc(R.color.warning) + "'>" + MainApp.gs(R.string.constraintapllied) + "</font>")
activity?.let { activity ->
OKDialog.showConfirmation(activity, MainApp.gs(R.string.extended_bolus), HtmlHelper.fromHtml(Joiner.on("<br/>").join(actions)), Runnable {
ConfigBuilderPlugin.getPlugin().commandQueue.extendedBolus(insulinAfterConstraint, durationInMinutes, object : Callback() {
override fun run() {
if (!result.success) {
val i = Intent(MainApp.instance(), ErrorHelperActivity::class.java)
i.putExtra("soundid", R.raw.boluserror)
i.putExtra("status", result.comment)
i.putExtra("title", MainApp.gs(R.string.treatmentdeliveryerror))
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
MainApp.instance().startActivity(i)
}
}
})
}, null)
}
return true
}
}

View file

@ -0,0 +1,132 @@
package info.nightscout.androidaps.dialogs
import android.content.Intent
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.google.common.base.Joiner
import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R
import info.nightscout.androidaps.activities.ErrorHelperActivity
import info.nightscout.androidaps.data.DetailedBolusInfo
import info.nightscout.androidaps.db.CareportalEvent
import info.nightscout.androidaps.db.Source
import info.nightscout.androidaps.interfaces.Constraint
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload
import info.nightscout.androidaps.queue.Callback
import info.nightscout.androidaps.utils.*
import kotlinx.android.synthetic.main.dialog_fill.*
import kotlinx.android.synthetic.main.notes.*
import kotlinx.android.synthetic.main.okcancel.*
import java.util.*
import kotlin.math.abs
class FillDialog : DialogFragmentWithDate() {
override fun onSaveInstanceState(savedInstanceState: Bundle) {
super.onSaveInstanceState(savedInstanceState)
savedInstanceState.putDouble("fill_insulinamount", fill_insulinamount.value)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
onCreateViewGeneral()
return inflater.inflate(R.layout.dialog_fill, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val maxInsulin = MainApp.getConstraintChecker().maxBolusAllowed.value()
val bolusStep = ConfigBuilderPlugin.getPlugin().activePump!!.pumpDescription.bolusStep
fill_insulinamount.setParams(savedInstanceState?.getDouble("fill_insulinamount")
?: 0.0, 0.0, maxInsulin, bolusStep, DecimalFormatter.pumpSupportedBolusFormat(), true, ok)
val amount1 = SP.getDouble("fill_button1", 0.3)
if (amount1 > 0) {
fill_preset_button1.visibility = View.VISIBLE
fill_preset_button1.text = DecimalFormatter.toPumpSupportedBolus(amount1) // + "U");
fill_preset_button1.setOnClickListener { fill_insulinamount.value = amount1 }
} else {
fill_preset_button1.visibility = View.GONE
}
val amount2 = SP.getDouble("fill_button2", 0.0)
if (amount2 > 0) {
fill_preset_button2.visibility = View.VISIBLE
fill_preset_button2.text = DecimalFormatter.toPumpSupportedBolus(amount2) // + "U");
fill_preset_button2.setOnClickListener { fill_insulinamount.value = amount2 }
} else {
fill_preset_button2.visibility = View.GONE
}
val amount3 = SP.getDouble("fill_button3", 0.0)
if (amount3 > 0) {
fill_preset_button3.visibility = View.VISIBLE
fill_preset_button3.text = DecimalFormatter.toPumpSupportedBolus(amount3) // + "U");
fill_preset_button3.setOnClickListener { fill_insulinamount.value = amount3 }
} else {
fill_preset_button3.visibility = View.GONE
}
}
override fun submit(): Boolean {
val insulin = SafeParse.stringToDouble(fill_insulinamount.text)
val actions: LinkedList<String?> = LinkedList()
val insulinAfterConstraints = MainApp.getConstraintChecker().applyBolusConstraints(Constraint(insulin)).value()
if (insulinAfterConstraints > 0) {
actions.add(MainApp.gs(R.string.fillwarning))
actions.add("")
actions.add(MainApp.gs(R.string.bolus) + ": " + "<font color='" + MainApp.gc(R.color.colorInsulinButton) + "'>" + DecimalFormatter.toPumpSupportedBolus(insulinAfterConstraints) + MainApp.gs(R.string.insulin_unit_shortname) + "</font>")
if (abs(insulinAfterConstraints - insulin) > 0.01)
actions.add(MainApp.gs(R.string.bolusconstraintappliedwarning, MainApp.gc(R.color.warning), insulin, insulinAfterConstraints))
}
val siteChange = fill_catheter_change.isChecked
if (siteChange)
actions.add("" + "<font color='" + MainApp.gc(R.color.actionsConfirm) + "'>" + MainApp.gs(R.string.record_pump_site_change) + "</font>")
val insulinChange = fill_cartridge_change.isChecked
if (insulinChange)
actions.add("" + "<font color='" + MainApp.gc(R.color.actionsConfirm) + "'>" + MainApp.gs(R.string.record_insulin_cartridge_change) + "</font>")
val notes = notes.text.toString()
if (notes.isNotEmpty())
actions.add(MainApp.gs(R.string.careportal_newnstreatment_notes_label) + ": " + notes)
if (eventTimeChanged)
actions.add(MainApp.gs(R.string.time) + ": " + DateUtil.dateAndTimeString(eventTime))
if (insulinAfterConstraints > 0 || fill_catheter_change.isChecked || fill_cartridge_change.isChecked) {
activity?.let { activity ->
OKDialog.showConfirmation(activity, MainApp.gs(R.string.primefill), HtmlHelper.fromHtml(Joiner.on("<br/>").join(actions)), Runnable {
if (insulinAfterConstraints > 0) {
val detailedBolusInfo = DetailedBolusInfo()
detailedBolusInfo.insulin = insulinAfterConstraints
detailedBolusInfo.context = context
detailedBolusInfo.source = Source.USER
detailedBolusInfo.isValid = false // do not count it in IOB (for pump history)
detailedBolusInfo.notes = notes
ConfigBuilderPlugin.getPlugin().commandQueue.bolus(detailedBolusInfo, object : Callback() {
override fun run() {
if (!result.success) {
val i = Intent(MainApp.instance(), ErrorHelperActivity::class.java)
i.putExtra("soundid", R.raw.boluserror)
i.putExtra("status", result.comment)
i.putExtra("title", MainApp.gs(R.string.treatmentdeliveryerror))
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
MainApp.instance().startActivity(i)
}
}
})
}
if (siteChange) NSUpload.uploadEvent(CareportalEvent.SITECHANGE, eventTime, notes)
if (insulinChange) NSUpload.uploadEvent(CareportalEvent.INSULINCHANGE, eventTime + 1000, notes)
}, null)
}
} else {
activity?.let { activity ->
OKDialog.show(activity, MainApp.gs(R.string.primefill), MainApp.gs(R.string.no_action_selected))
}
}
dismiss()
return true
}
}

View file

@ -0,0 +1,193 @@
package info.nightscout.androidaps.dialogs
import android.content.Intent
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.google.common.base.Joiner
import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R
import info.nightscout.androidaps.activities.ErrorHelperActivity
import info.nightscout.androidaps.data.DetailedBolusInfo
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.db.CareportalEvent
import info.nightscout.androidaps.db.Source
import info.nightscout.androidaps.db.TempTarget
import info.nightscout.androidaps.interfaces.Constraint
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
import info.nightscout.androidaps.queue.Callback
import info.nightscout.androidaps.utils.*
import kotlinx.android.synthetic.main.dialog_insulin.*
import kotlinx.android.synthetic.main.notes.*
import kotlinx.android.synthetic.main.okcancel.*
import java.text.DecimalFormat
import java.util.*
import kotlin.math.abs
import kotlin.math.max
class InsulinDialog : DialogFragmentWithDate() {
companion object {
private const val PLUS1_DEFAULT = 0.5
private const val PLUS2_DEFAULT = 1.0
private const val PLUS3_DEFAULT = 2.0
}
private val maxInsulin = MainApp.getConstraintChecker().maxBolusAllowed.value()
private val textWatcher: TextWatcher = object : TextWatcher {
override fun afterTextChanged(s: Editable) {
validateInputs()
}
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {}
}
private fun validateInputs() {
if (abs(overview_insulin_time.value.toInt()) > 12 * 60) {
overview_insulin_time.value = 0.0
ToastUtils.showToastInUiThread(MainApp.instance().applicationContext, MainApp.gs(R.string.constraintapllied))
}
if (overview_insulin_amount.value > maxInsulin) {
overview_insulin_amount.value = 0.0
ToastUtils.showToastInUiThread(MainApp.instance().applicationContext, MainApp.gs(R.string.bolusconstraintapplied))
}
}
override fun onSaveInstanceState(savedInstanceState: Bundle) {
super.onSaveInstanceState(savedInstanceState)
savedInstanceState.putDouble("overview_insulin_time", overview_insulin_time.value)
savedInstanceState.putDouble("overview_insulin_amount", overview_insulin_amount.value)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
onCreateViewGeneral()
return inflater.inflate(R.layout.dialog_insulin, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
overview_insulin_time.setParams(savedInstanceState?.getDouble("overview_insulin_time")
?: 0.0, -12 * 60.0, 12 * 60.0, 5.0, DecimalFormat("0"), false, ok, textWatcher)
overview_insulin_amount.setParams(savedInstanceState?.getDouble("overview_insulin_amount")
?: 0.0, 0.0, maxInsulin, ConfigBuilderPlugin.getPlugin().activePump!!.pumpDescription.bolusStep, DecimalFormatter.pumpSupportedBolusFormat(), false, ok, textWatcher)
overview_insulin_plus05.text = toSignedString(SP.getDouble(MainApp.gs(R.string.key_insulin_button_increment_1), PLUS1_DEFAULT))
overview_insulin_plus05.setOnClickListener {
overview_insulin_amount.value = max(0.0, overview_insulin_amount.value
+ SP.getDouble(MainApp.gs(R.string.key_insulin_button_increment_1), PLUS1_DEFAULT))
validateInputs()
}
overview_insulin_plus10.text = toSignedString(SP.getDouble(MainApp.gs(R.string.key_insulin_button_increment_2), PLUS2_DEFAULT))
overview_insulin_plus10.setOnClickListener {
overview_insulin_amount.value = max(0.0, overview_insulin_amount.value
+ SP.getDouble(MainApp.gs(R.string.key_insulin_button_increment_2), PLUS2_DEFAULT))
validateInputs()
}
overview_insulin_plus20.text = toSignedString(SP.getDouble(MainApp.gs(R.string.key_insulin_button_increment_3), PLUS3_DEFAULT))
overview_insulin_plus20.setOnClickListener {
overview_insulin_amount.value = Math.max(0.0, overview_insulin_amount.value
+ SP.getDouble(MainApp.gs(R.string.key_insulin_button_increment_3), PLUS3_DEFAULT))
validateInputs()
}
overview_insulin_time_layout.visibility = View.GONE
overview_insulin_record_only.setOnCheckedChangeListener { _, isChecked: Boolean ->
overview_insulin_time_layout.visibility = isChecked.toVisibility()
}
}
private fun toSignedString(value: Double): String {
val formatted = DecimalFormatter.toPumpSupportedBolus(value)
return if (value > 0) "+$formatted" else formatted
}
override fun submit(): Boolean {
val pumpDescription = ConfigBuilderPlugin.getPlugin().activePump?.pumpDescription
?: return false
val insulin = SafeParse.stringToDouble(overview_insulin_amount.text)
val insulinAfterConstraints = MainApp.getConstraintChecker().applyBolusConstraints(Constraint(insulin)).value()
val actions: LinkedList<String?> = LinkedList()
val units = ProfileFunctions.getSystemUnits()
val unitLabel = if (units == Constants.MMOL) MainApp.gs(R.string.mmol) else MainApp.gs(R.string.mgdl)
val recordOnlyChecked = overview_insulin_record_only.isChecked
val eatingSoonChecked = overview_insulin_start_eating_soon_tt.isChecked
if (insulinAfterConstraints > 0) {
actions.add(MainApp.gs(R.string.bolus) + ": " + "<font color='" + MainApp.gc(R.color.bolus) + "'>" + DecimalFormatter.toPumpSupportedBolus(insulinAfterConstraints) + MainApp.gs(R.string.insulin_unit_shortname) + "</font>")
if (recordOnlyChecked)
actions.add("<font color='" + MainApp.gc(R.color.warning) + "'>" + MainApp.gs(R.string.bolusrecordedonly) + "</font>")
if (abs(insulinAfterConstraints - insulin) > pumpDescription.pumpType.determineCorrectBolusStepSize(insulinAfterConstraints))
actions.add(MainApp.gs(R.string.bolusconstraintappliedwarning, MainApp.gc(R.color.warning), insulin, insulinAfterConstraints))
}
val eatingSoonTTDuration = DefaultValueHelper.determineEatingSoonTTDuration()
val eatingSoonTT = DefaultValueHelper.determineEatingSoonTT()
if (eatingSoonChecked)
actions.add(MainApp.gs(R.string.temptargetshort) + ": " + "<font color='" + MainApp.gc(R.color.tempTargetConfirmation) + "'>" + DecimalFormatter.to1Decimal(eatingSoonTT) + " " + unitLabel + " (" + eatingSoonTTDuration + " " + MainApp.gs(R.string.unit_minute_short) + ")</font>")
val timeOffset = overview_insulin_time.value.toInt()
val time = DateUtil.now() + T.mins(timeOffset.toLong()).msecs()
if (timeOffset != 0)
actions.add(MainApp.gs(R.string.time) + ": " + DateUtil.dateAndTimeString(time))
val notes = notes.text.toString()
if (notes.isNotEmpty())
actions.add(MainApp.gs(R.string.careportal_newnstreatment_notes_label) + ": " + notes)
if (insulinAfterConstraints > 0 || eatingSoonChecked) {
activity?.let { activity ->
OKDialog.showConfirmation(activity, MainApp.gs(R.string.bolus), HtmlHelper.fromHtml(Joiner.on("<br/>").join(actions)), Runnable {
if (eatingSoonChecked) {
val tempTarget = TempTarget()
.date(System.currentTimeMillis())
.duration(eatingSoonTTDuration)
.reason(MainApp.gs(R.string.eatingsoon))
.source(Source.USER)
.low(Profile.toMgdl(eatingSoonTT, ProfileFunctions.getSystemUnits()))
.high(Profile.toMgdl(eatingSoonTT, ProfileFunctions.getSystemUnits()))
TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget)
}
if (insulinAfterConstraints > 0) {
val detailedBolusInfo = DetailedBolusInfo()
detailedBolusInfo.eventType = CareportalEvent.CORRECTIONBOLUS
detailedBolusInfo.insulin = insulinAfterConstraints
detailedBolusInfo.context = context
detailedBolusInfo.source = Source.USER
detailedBolusInfo.notes = notes
if (recordOnlyChecked) {
detailedBolusInfo.date = time
TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo, false)
} else {
detailedBolusInfo.date = DateUtil.now()
ConfigBuilderPlugin.getPlugin().commandQueue.bolus(detailedBolusInfo, object : Callback() {
override fun run() {
if (!result.success) {
val i = Intent(MainApp.instance(), ErrorHelperActivity::class.java)
i.putExtra("soundid", R.raw.boluserror)
i.putExtra("status", result.comment)
i.putExtra("title", MainApp.gs(R.string.treatmentdeliveryerror))
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
MainApp.instance().startActivity(i)
}
}
})
}
}
})
}
} else
activity?.let { activity ->
OKDialog.show(activity, MainApp.gs(R.string.bolus), MainApp.gs(R.string.no_action_selected))
}
return true
}
}

View file

@ -0,0 +1,105 @@
package info.nightscout.androidaps.dialogs
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ArrayAdapter
import com.google.common.base.Joiner
import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.HtmlHelper
import info.nightscout.androidaps.utils.OKDialog
import kotlinx.android.synthetic.main.dialog_profileswitch.*
import kotlinx.android.synthetic.main.notes.*
import kotlinx.android.synthetic.main.okcancel.*
import java.text.DecimalFormat
import java.util.*
class ProfileSwitchDialog : DialogFragmentWithDate() {
override fun onSaveInstanceState(savedInstanceState: Bundle) {
super.onSaveInstanceState(savedInstanceState)
savedInstanceState.putDouble("overview_profileswitch_duration", overview_profileswitch_duration.value)
savedInstanceState.putDouble("overview_profileswitch_percentage", overview_profileswitch_percentage.value)
savedInstanceState.putDouble("overview_profileswitch_timeshift", overview_profileswitch_timeshift.value)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
onCreateViewGeneral()
return inflater.inflate(R.layout.dialog_profileswitch, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
overview_profileswitch_duration.setParams(savedInstanceState?.getDouble("overview_profileswitch_duration")
?: 0.0, 0.0, Constants.MAX_PROFILE_SWITCH_DURATION, 10.0, DecimalFormat("0"), false, ok)
overview_profileswitch_percentage.setParams(savedInstanceState?.getDouble("overview_profileswitch_percentage")
?: 100.0, Constants.CPP_MIN_PERCENTAGE.toDouble(), Constants.CPP_MAX_PERCENTAGE.toDouble(), 1.0, DecimalFormat("0"), false, ok)
overview_profileswitch_timeshift.setParams(savedInstanceState?.getDouble("overview_profileswitch_timeshift")
?: 0.0, Constants.CPP_MIN_TIMESHIFT.toDouble(), Constants.CPP_MAX_TIMESHIFT.toDouble(), 1.0, DecimalFormat("0"), false, ok)
// profile
context?.let { context ->
val profileStore = ConfigBuilderPlugin.getPlugin().activeProfileInterface?.profile
?: return
val profileList = profileStore.getProfileList()
val adapter = ArrayAdapter(context, R.layout.spinner_centered, profileList)
overview_profileswitch_profile.adapter = adapter
// set selected to actual profile
for (p in profileList.indices)
if (profileList[p] == ProfileFunctions.getInstance().getProfileName(false))
overview_profileswitch_profile.setSelection(p)
} ?: return
TreatmentsPlugin.getPlugin().getProfileSwitchFromHistory(DateUtil.now())?.let { ps ->
if (ps.isCPP) {
overview_profileswitch_reuselayout.visibility = View.VISIBLE
overview_profileswitch_reusebutton.text = MainApp.gs(R.string.reuse) + " " + ps.percentage + "% " + ps.timeshift + "h"
overview_profileswitch_reusebutton.setOnClickListener {
overview_profileswitch_percentage.value = ps.percentage.toDouble()
overview_profileswitch_timeshift.value = ps.timeshift.toDouble()
}
} else {
overview_profileswitch_reuselayout.visibility = View.GONE
}
}
}
override fun submit(): Boolean {
val profileStore = ConfigBuilderPlugin.getPlugin().activeProfileInterface?.profile
?: return false
val actions: LinkedList<String> = LinkedList()
val duration = overview_profileswitch_duration.value
if (duration > 0)
actions.add(MainApp.gs(R.string.duration) + ": " + MainApp.gs(R.string.format_hours, duration))
val profile = overview_profileswitch_profile.selectedItem.toString()
actions.add(MainApp.gs(R.string.profile) + ": " + profile)
val percent = overview_profileswitch_percentage.value.toInt()
if (percent != 100)
actions.add(MainApp.gs(R.string.percent) + ": " + percent + "%")
val timeShift = overview_profileswitch_timeshift.value.toInt()
if (timeShift != 0)
actions.add(MainApp.gs(R.string.careportal_newnstreatment_timeshift_label) + ": " + MainApp.gs(R.string.format_hours, timeShift.toDouble()))
val notes = notes.text.toString()
if (notes.isNotEmpty())
actions.add(MainApp.gs(R.string.careportal_newnstreatment_notes_label) + ": " + notes)
if (eventTimeChanged)
actions.add(MainApp.gs(R.string.time) + ": " + DateUtil.dateAndTimeString(eventTime))
activity?.let { activity ->
OKDialog.showConfirmation(activity, MainApp.gs(R.string.careportal_profileswitch), HtmlHelper.fromHtml(Joiner.on("<br/>").join(actions)), Runnable {
ProfileFunctions.getInstance().doProfileSwitch(profileStore, profile, duration.toInt(), percent, timeShift, eventTime)
})
}
return true
}
}

View file

@ -1,20 +1,20 @@
package info.nightscout.androidaps.plugins.treatments.fragments package info.nightscout.androidaps.dialogs
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.view.Window
import android.view.WindowManager
import androidx.fragment.app.DialogFragment import androidx.fragment.app.DialogFragment
import info.nightscout.androidaps.Constants import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.MainApp import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.Profile import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.interfaces.ProfileInterface
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.DateUtil
import kotlinx.android.synthetic.main.close.* import kotlinx.android.synthetic.main.close.*
import kotlinx.android.synthetic.main.profileviewer_fragment.* import kotlinx.android.synthetic.main.dialog_profileviewer.*
import org.json.JSONObject import org.json.JSONObject
class ProfileViewerDialog : DialogFragment() { class ProfileViewerDialog : DialogFragment() {
@ -22,8 +22,7 @@ class ProfileViewerDialog : DialogFragment() {
enum class Mode(val i: Int) { enum class Mode(val i: Int) {
RUNNING_PROFILE(1), RUNNING_PROFILE(1),
PUMP_PROFILE(2), CUSTOM_PROFILE(2)
CUSTOM_PROFILE(3)
} }
private var mode: Mode = Mode.RUNNING_PROFILE private var mode: Mode = Mode.RUNNING_PROFILE
@ -42,17 +41,18 @@ class ProfileViewerDialog : DialogFragment() {
customProfileName = bundle.getString("customProfileName", "") customProfileName = bundle.getString("customProfileName", "")
} }
return inflater.inflate(R.layout.profileviewer_fragment, container, false) dialog?.window?.requestFeature(Window.FEATURE_NO_TITLE)
dialog?.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN)
isCancelable = true
dialog?.setCanceledOnTouchOutside(false)
return inflater.inflate(R.layout.dialog_profileviewer, container, false)
} }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
close.setOnClickListener { dismiss() } close.setOnClickListener { dismiss() }
profileview_reload.setOnClickListener {
ConfigBuilderPlugin.getPlugin().commandQueue.readStatus("ProfileViewDialog", null)
dismiss()
}
val profile: Profile? val profile: Profile?
val profileName: String? val profileName: String?
@ -63,21 +63,13 @@ class ProfileViewerDialog : DialogFragment() {
profileName = TreatmentsPlugin.getPlugin().getProfileSwitchFromHistory(time)?.customizedName profileName = TreatmentsPlugin.getPlugin().getProfileSwitchFromHistory(time)?.customizedName
date = DateUtil.dateAndTimeString(TreatmentsPlugin.getPlugin().getProfileSwitchFromHistory(time)?.date date = DateUtil.dateAndTimeString(TreatmentsPlugin.getPlugin().getProfileSwitchFromHistory(time)?.date
?: 0) ?: 0)
profileview_reload.visibility = View.GONE
profileview_datelayout.visibility = View.VISIBLE profileview_datelayout.visibility = View.VISIBLE
} }
Mode.PUMP_PROFILE -> {
profile = (ConfigBuilderPlugin.getPlugin().activePump as ProfileInterface?)?.profile?.getDefaultProfile()
profileName = (ConfigBuilderPlugin.getPlugin().activePump as ProfileInterface?)?.profileName
date = ""
profileview_reload.visibility = View.VISIBLE
profileview_datelayout.visibility = View.GONE
}
Mode.CUSTOM_PROFILE -> { Mode.CUSTOM_PROFILE -> {
profile = Profile(JSONObject(customProfileJson), customProfileUnits) profile = Profile(JSONObject(customProfileJson), customProfileUnits)
profileName = customProfileName profileName = customProfileName
date = "" date = ""
profileview_reload.visibility = View.GONE
profileview_datelayout.visibility = View.GONE profileview_datelayout.visibility = View.GONE
} }
} }
@ -99,9 +91,9 @@ class ProfileViewerDialog : DialogFragment() {
} }
} }
override fun onResume() { override fun onStart() {
super.onStart()
dialog?.window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT) dialog?.window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
super.onResume()
} }
override fun onSaveInstanceState(bundle: Bundle) { override fun onSaveInstanceState(bundle: Bundle) {

View file

@ -0,0 +1,115 @@
package info.nightscout.androidaps.dialogs
import android.content.Intent
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.google.common.base.Joiner
import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R
import info.nightscout.androidaps.activities.ErrorHelperActivity
import info.nightscout.androidaps.interfaces.Constraint
import info.nightscout.androidaps.interfaces.PumpDescription
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions
import info.nightscout.androidaps.queue.Callback
import info.nightscout.androidaps.utils.HtmlHelper
import info.nightscout.androidaps.utils.OKDialog
import info.nightscout.androidaps.utils.SafeParse
import kotlinx.android.synthetic.main.dialog_tempbasal.*
import kotlinx.android.synthetic.main.okcancel.*
import java.text.DecimalFormat
import java.util.*
import kotlin.math.abs
class TempBasalDialog : DialogFragmentWithDate() {
private var isPercentPump = true
override fun onSaveInstanceState(savedInstanceState: Bundle) {
super.onSaveInstanceState(savedInstanceState)
savedInstanceState.putDouble("actions_tempbasal_duration", actions_tempbasal_duration.value)
savedInstanceState.putDouble("actions_tempbasal_basalpercentinput", actions_tempbasal_basalpercentinput.value)
savedInstanceState.putDouble("actions_tempbasal_basalabsoluteinput", actions_tempbasal_basalabsoluteinput.value)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
onCreateViewGeneral()
return inflater.inflate(R.layout.dialog_tempbasal, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val pumpDescription = ConfigBuilderPlugin.getPlugin().activePump?.pumpDescription ?: return
val profile = ProfileFunctions.getInstance().getProfile() ?: return
val maxTempPercent = pumpDescription.maxTempPercent.toDouble()
val tempPercentStep = pumpDescription.tempPercentStep.toDouble()
actions_tempbasal_basalpercentinput.setParams(savedInstanceState?.getDouble("actions_tempbasal_basalpercentinput")
?: 100.0, 0.0, maxTempPercent, tempPercentStep, DecimalFormat("0"), true, ok)
actions_tempbasal_basalabsoluteinput.setParams(savedInstanceState?.getDouble("actions_tempbasal_basalabsoluteinput")
?: profile.basal, 0.0, pumpDescription.maxTempAbsolute, pumpDescription.tempAbsoluteStep, DecimalFormat("0.00"), true, ok)
val tempDurationStep = pumpDescription.tempDurationStep.toDouble()
val tempMaxDuration = pumpDescription.tempMaxDuration.toDouble()
actions_tempbasal_duration.setParams(savedInstanceState?.getDouble("actions_tempbasal_duration")
?: tempDurationStep, tempDurationStep, tempMaxDuration, tempDurationStep, DecimalFormat("0"), false, ok)
isPercentPump = pumpDescription.tempBasalStyle and PumpDescription.PERCENT == PumpDescription.PERCENT
if (isPercentPump) {
actions_tempbasal_percent_layout.visibility = View.VISIBLE
actions_tempbasal_absolute_layout.visibility = View.GONE
} else {
actions_tempbasal_percent_layout.visibility = View.GONE
actions_tempbasal_absolute_layout.visibility = View.VISIBLE
}
}
override fun submit(): Boolean {
var percent = 0
var absolute = 0.0
val durationInMinutes = SafeParse.stringToInt(actions_tempbasal_duration.text)
val profile = ProfileFunctions.getInstance().getProfile() ?: return false
val actions: LinkedList<String> = LinkedList()
if (isPercentPump) {
val basalPercentInput = SafeParse.stringToInt(actions_tempbasal_basalpercentinput.text)
percent = MainApp.getConstraintChecker().applyBasalPercentConstraints(Constraint(basalPercentInput), profile).value()
actions.add(MainApp.gs(R.string.pump_tempbasal_label)+ ": $percent%")
actions.add(MainApp.gs(R.string.duration) + ": " + MainApp.gs(R.string.format_mins, durationInMinutes))
if (percent != basalPercentInput) actions.add(MainApp.gs(R.string.constraintapllied))
} else {
val basalAbsoluteInput = SafeParse.stringToDouble(actions_tempbasal_basalabsoluteinput.text)
absolute = MainApp.getConstraintChecker().applyBasalConstraints(Constraint(basalAbsoluteInput), profile).value()
actions.add(MainApp.gs(R.string.pump_tempbasal_label)+ ": " + MainApp.gs(R.string.pump_basebasalrate, absolute))
actions.add(MainApp.gs(R.string.duration) + ": " + MainApp.gs(R.string.format_mins, durationInMinutes))
if (abs(absolute - basalAbsoluteInput) > 0.01)
actions.add("<font color='" + MainApp.gc(R.color.warning) + "'>" + MainApp.gs(R.string.constraintapllied) + "</font>")
}
activity?.let { activity ->
OKDialog.showConfirmation(activity, MainApp.gs(R.string.pump_tempbasal_label), HtmlHelper.fromHtml(Joiner.on("<br/>").join(actions)), Runnable {
val callback: Callback = object : Callback() {
override fun run() {
if (!result.success) {
val i = Intent(MainApp.instance(), ErrorHelperActivity::class.java)
i.putExtra("soundid", R.raw.boluserror)
i.putExtra("status", result.comment)
i.putExtra("title", MainApp.gs(R.string.tempbasaldeliveryerror))
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
MainApp.instance().startActivity(i)
}
}
}
if (isPercentPump) {
ConfigBuilderPlugin.getPlugin().commandQueue.tempBasalPercent(percent, durationInMinutes, true, profile, callback)
} else {
ConfigBuilderPlugin.getPlugin().commandQueue.tempBasalAbsolute(absolute, durationInMinutes, true, profile, callback)
}
})
}
return true
}
}

View file

@ -0,0 +1,152 @@
package info.nightscout.androidaps.dialogs
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.AdapterView
import android.widget.ArrayAdapter
import com.google.common.base.Joiner
import com.google.common.collect.Lists
import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.db.Source
import info.nightscout.androidaps.db.TempTarget
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.DefaultValueHelper
import info.nightscout.androidaps.utils.HtmlHelper
import info.nightscout.androidaps.utils.OKDialog
import info.nightscout.androidaps.utils.SP
import kotlinx.android.synthetic.main.dialog_temptarget.*
import kotlinx.android.synthetic.main.okcancel.*
import java.text.DecimalFormat
import java.util.*
class TempTargetDialog : DialogFragmentWithDate() {
override fun onSaveInstanceState(savedInstanceState: Bundle) {
super.onSaveInstanceState(savedInstanceState)
savedInstanceState.putDouble("overview_temptarget_duration", overview_temptarget_duration.value)
savedInstanceState.putDouble("overview_temptarget_temptarget", overview_temptarget_temptarget.value)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
onCreateViewGeneral()
return inflater.inflate(R.layout.dialog_temptarget, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
overview_temptarget_duration.setParams(savedInstanceState?.getDouble("overview_temptarget_duration")
?: 0.0, 0.0, Constants.MAX_PROFILE_SWITCH_DURATION, 10.0, DecimalFormat("0"), false, ok)
if (ProfileFunctions.getSystemUnits() == Constants.MMOL)
overview_temptarget_temptarget.setParams(
savedInstanceState?.getDouble("overview_temptarget_temptarget")
?: Constants.MIN_TT_MMOL,
Constants.MIN_TT_MMOL, Constants.MAX_TT_MMOL, 0.1, DecimalFormat("0.0"), false, ok)
else
overview_temptarget_temptarget.setParams(
savedInstanceState?.getDouble("overview_temptarget_temptarget")
?: Constants.MIN_TT_MGDL,
Constants.MIN_TT_MGDL, Constants.MAX_TT_MGDL, 1.0, DecimalFormat("0"), false, ok)
val units = ProfileFunctions.getSystemUnits()
overview_temptarget_units.text = if (units == Constants.MMOL) MainApp.gs(R.string.mmol) else MainApp.gs(R.string.mgdl)
// temp target
context?.let { context ->
val reasonList: List<String> = Lists.newArrayList(
MainApp.gs(R.string.manual),
MainApp.gs(R.string.cancel),
MainApp.gs(R.string.eatingsoon),
MainApp.gs(R.string.activity),
MainApp.gs(R.string.hypo)
)
val adapterReason = ArrayAdapter(context, R.layout.spinner_centered, reasonList)
overview_temptarget_reason.adapter = adapterReason
overview_temptarget_reason.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(parent: AdapterView<*>?, view: View, position: Int, id: Long) {
val defaultDuration: Double
val defaultTarget: Double
when (reasonList[position]) {
MainApp.gs(R.string.eatingsoon) -> {
defaultDuration = DefaultValueHelper.determineEatingSoonTTDuration().toDouble()
defaultTarget = DefaultValueHelper.determineEatingSoonTT()
}
MainApp.gs(R.string.activity) -> {
defaultDuration = DefaultValueHelper.determineActivityTTDuration().toDouble()
defaultTarget = DefaultValueHelper.determineActivityTT()
}
MainApp.gs(R.string.hypo) -> {
defaultDuration = DefaultValueHelper.determineHypoTTDuration().toDouble()
defaultTarget = DefaultValueHelper.determineHypoTT()
}
MainApp.gs(R.string.cancel) -> {
defaultDuration = 0.0
defaultTarget = 0.0
}
else -> {
defaultDuration = overview_temptarget_duration.value
defaultTarget = overview_temptarget_temptarget.value
}
}
overview_temptarget_temptarget.value = defaultTarget
overview_temptarget_duration.value = defaultDuration
}
override fun onNothingSelected(parent: AdapterView<*>?) {}
}
}
}
override fun submit(): Boolean {
val actions: LinkedList<String> = LinkedList()
val reason = overview_temptarget_reason.selectedItem.toString()
val unitResId = if (ProfileFunctions.getSystemUnits() == Constants.MGDL) R.string.mgdl else R.string.mmol
val target = overview_temptarget_temptarget.value
val duration = overview_temptarget_duration.value
if (target != 0.0 && duration != 0.0) {
actions.add(MainApp.gs(R.string.reason) + ": " + reason)
actions.add(MainApp.gs(R.string.nsprofileview_target_label) + ": " + Profile.toCurrentUnitsString(target) + " " + MainApp.gs(unitResId))
actions.add(MainApp.gs(R.string.duration) + ": " + MainApp.gs(R.string.format_hours, duration))
} else {
actions.add(MainApp.gs(R.string.stoptemptarget))
}
if (eventTimeChanged)
actions.add(MainApp.gs(R.string.time) + ": " + DateUtil.dateAndTimeString(eventTime))
activity?.let { activity ->
OKDialog.showConfirmation(activity, MainApp.gs(R.string.careportal_temporarytarget), HtmlHelper.fromHtml(Joiner.on("<br/>").join(actions)), Runnable {
if (target == 0.0 || duration == 0.0) {
val tempTarget = TempTarget()
.date(eventTime)
.duration(0)
.low(0.0).high(0.0)
.source(Source.USER)
TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget)
} else {
val tempTarget = TempTarget()
.date(eventTime)
.duration(duration.toInt())
.reason(reason)
.source(Source.USER)
.low(Profile.toMgdl(target, ProfileFunctions.getSystemUnits()))
.high(Profile.toMgdl(target, ProfileFunctions.getSystemUnits()))
TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget)
}
if (duration == 10.0) SP.putBoolean(R.string.key_objectiveusetemptarget, true)
})
}
return true
}
}

View file

@ -0,0 +1,132 @@
package info.nightscout.androidaps.dialogs
import android.content.Intent
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.google.common.base.Joiner
import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R
import info.nightscout.androidaps.activities.ErrorHelperActivity
import info.nightscout.androidaps.data.DetailedBolusInfo
import info.nightscout.androidaps.db.CareportalEvent
import info.nightscout.androidaps.db.Source
import info.nightscout.androidaps.interfaces.Constraint
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
import info.nightscout.androidaps.queue.Callback
import info.nightscout.androidaps.utils.DecimalFormatter
import info.nightscout.androidaps.utils.HtmlHelper
import info.nightscout.androidaps.utils.OKDialog
import info.nightscout.androidaps.utils.SafeParse
import info.nightscout.androidaps.utils.ToastUtils
import kotlinx.android.synthetic.main.dialog_treatment.*
import kotlinx.android.synthetic.main.okcancel.*
import java.text.DecimalFormat
import java.util.*
import kotlin.math.abs
class TreatmentDialog : DialogFragmentWithDate() {
private var maxCarbs = MainApp.getConstraintChecker().maxCarbsAllowed.value().toDouble()
private var maxInsulin = MainApp.getConstraintChecker().maxBolusAllowed.value()
private val textWatcher: TextWatcher = object : TextWatcher {
override fun afterTextChanged(s: Editable) {}
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
validateInputs()
}
}
private fun validateInputs() {
if (SafeParse.stringToInt(overview_treatment_carbs.text) > maxCarbs) {
overview_treatment_carbs.value = 0.0
ToastUtils.showToastInUiThread(MainApp.instance().applicationContext, MainApp.gs(R.string.carbsconstraintapplied))
}
if (SafeParse.stringToDouble(overview_treatment_insulin.text) > maxInsulin) {
overview_treatment_insulin.value = 0.0
ToastUtils.showToastInUiThread(MainApp.instance().applicationContext, MainApp.gs(R.string.bolusconstraintapplied))
}
}
override fun onSaveInstanceState(savedInstanceState: Bundle) {
super.onSaveInstanceState(savedInstanceState)
savedInstanceState.putDouble("overview_treatment_carbs", overview_treatment_carbs.value)
savedInstanceState.putDouble("overview_treatment_insulin", overview_treatment_insulin.value)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
onCreateViewGeneral()
return inflater.inflate(R.layout.dialog_treatment, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val pumpDescription = ConfigBuilderPlugin.getPlugin().activePump?.pumpDescription ?: return
overview_treatment_carbs.setParams(savedInstanceState?.getDouble("overview_treatment_carbs")
?: 0.0, 0.0, maxCarbs, 1.0, DecimalFormat("0"), false, ok, textWatcher)
overview_treatment_insulin.setParams(savedInstanceState?.getDouble("overview_treatment_insulin")
?: 0.0, 0.0, maxInsulin, pumpDescription.bolusStep, DecimalFormatter.pumpSupportedBolusFormat(), false, ok, textWatcher)
}
override fun submit(): Boolean {
val pumpDescription = ConfigBuilderPlugin.getPlugin().activePump?.pumpDescription
?: return false
val insulin = SafeParse.stringToDouble(overview_treatment_insulin.text)
val carbs = SafeParse.stringToInt(overview_treatment_carbs.text)
val recordOnlyChecked = overview_treatment_record_only.isChecked
val actions: LinkedList<String?> = LinkedList()
val insulinAfterConstraints = MainApp.getConstraintChecker().applyBolusConstraints(Constraint(insulin)).value()
val carbsAfterConstraints = MainApp.getConstraintChecker().applyCarbsConstraints(Constraint(carbs)).value()
if (insulinAfterConstraints > 0) {
actions.add(MainApp.gs(R.string.bolus) + ": " + "<font color='" + MainApp.gc(R.color.bolus) + "'>" + DecimalFormatter.toPumpSupportedBolus(insulinAfterConstraints) + MainApp.gs(R.string.insulin_unit_shortname) + "</font>")
if (recordOnlyChecked)
actions.add("<font color='" + MainApp.gc(R.color.warning) + "'>" + MainApp.gs(R.string.bolusrecordedonly) + "</font>")
if (abs(insulinAfterConstraints - insulin) > pumpDescription.pumpType.determineCorrectBolusStepSize(insulinAfterConstraints))
actions.add(MainApp.gs(R.string.bolusconstraintappliedwarning, MainApp.gc(R.color.warning), insulin, insulinAfterConstraints))
}
if (carbsAfterConstraints > 0) {
actions.add(MainApp.gs(R.string.carbs) + ": " + "<font color='" + MainApp.gc(R.color.carbs) + "'>" + MainApp.gs(R.string.format_carbs, carbsAfterConstraints) + "</font>")
if (carbsAfterConstraints != carbs)
actions.add("<font color='" + MainApp.gc(R.color.warning) + "'>" + MainApp.gs(R.string.carbsconstraintapplied) + "</font>")
}
if (insulinAfterConstraints > 0 || carbsAfterConstraints > 0) {
activity?.let { activity ->
OKDialog.showConfirmation(activity, MainApp.gs(R.string.overview_treatment_label), HtmlHelper.fromHtml(Joiner.on("<br/>").join(actions)), Runnable {
val detailedBolusInfo = DetailedBolusInfo()
if (insulinAfterConstraints == 0.0) detailedBolusInfo.eventType = CareportalEvent.CARBCORRECTION
if (carbsAfterConstraints == 0) detailedBolusInfo.eventType = CareportalEvent.CORRECTIONBOLUS
detailedBolusInfo.insulin = insulinAfterConstraints
detailedBolusInfo.carbs = carbsAfterConstraints.toDouble()
detailedBolusInfo.context = context
detailedBolusInfo.source = Source.USER
if (!(recordOnlyChecked && (detailedBolusInfo.insulin > 0 || pumpDescription.storesCarbInfo))) {
ConfigBuilderPlugin.getPlugin().commandQueue.bolus(detailedBolusInfo, object : Callback() {
override fun run() {
if (!result.success) {
val i = Intent(MainApp.instance(), ErrorHelperActivity::class.java)
i.putExtra("soundid", R.raw.boluserror)
i.putExtra("status", result.comment)
i.putExtra("title", MainApp.gs(R.string.treatmentdeliveryerror))
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
MainApp.instance().startActivity(i)
}
}
})
} else
TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo, false)
})
}
} else
activity?.let { activity ->
OKDialog.show(activity, MainApp.gs(R.string.overview_treatment_label), MainApp.gs(R.string.no_action_selected))
}
return true
}
}

View file

@ -1,10 +1,13 @@
package info.nightscout.androidaps.plugins.general.overview.dialogs package info.nightscout.androidaps.dialogs
import android.content.Context
import android.os.Bundle import android.os.Bundle
import android.text.Editable import android.text.Editable
import android.text.TextWatcher import android.text.TextWatcher
import android.view.* import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.Window
import android.view.WindowManager
import android.widget.AdapterView import android.widget.AdapterView
import android.widget.AdapterView.OnItemSelectedListener import android.widget.AdapterView.OnItemSelectedListener
import android.widget.ArrayAdapter import android.widget.ArrayAdapter
@ -26,7 +29,7 @@ import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
import info.nightscout.androidaps.utils.* import info.nightscout.androidaps.utils.*
import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable import io.reactivex.disposables.CompositeDisposable
import kotlinx.android.synthetic.main.overview_wizard_dialog.* import kotlinx.android.synthetic.main.dialog_wizard.*
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory
import java.text.DecimalFormat import java.text.DecimalFormat
import java.util.* import java.util.*
@ -36,16 +39,13 @@ class WizardDialog : DialogFragment() {
private val log = LoggerFactory.getLogger(WizardDialog::class.java) private val log = LoggerFactory.getLogger(WizardDialog::class.java)
private var wizard: BolusWizard? = null private var wizard: BolusWizard? = null
private var parentContext: Context? = null
//one shot guards //one shot guards
private var okClicked: Boolean = false private var okClicked: Boolean = false
private val textWatcher = object : TextWatcher { private val textWatcher = object : TextWatcher {
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) {
calculateInsulin() calculateInsulin()
} }
@ -53,21 +53,11 @@ class WizardDialog : DialogFragment() {
private var disposable: CompositeDisposable = CompositeDisposable() private var disposable: CompositeDisposable = CompositeDisposable()
override fun onAttach(context: Context) {
super.onAttach(context)
this.parentContext = context
}
override fun onStart() { override fun onStart() {
super.onStart() super.onStart()
dialog?.window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT) dialog?.window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
} }
override fun onDetach() {
super.onDetach()
this.parentContext = null
}
override fun onSaveInstanceState(savedInstanceState: Bundle) { override fun onSaveInstanceState(savedInstanceState: Bundle) {
super.onSaveInstanceState(savedInstanceState) super.onSaveInstanceState(savedInstanceState)
savedInstanceState.putDouble("treatments_wizard_bg_input", treatments_wizard_bg_input.value) savedInstanceState.putDouble("treatments_wizard_bg_input", treatments_wizard_bg_input.value)
@ -83,14 +73,14 @@ class WizardDialog : DialogFragment() {
isCancelable = true isCancelable = true
dialog?.setCanceledOnTouchOutside(false) dialog?.setCanceledOnTouchOutside(false)
return inflater.inflate(R.layout.overview_wizard_dialog, container, false) return inflater.inflate(R.layout.dialog_wizard, container, false)
} }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
loadCheckedStates() loadCheckedStates()
processCobCheckBox() processCobCheckBox()
treatments_wizard_sbcheckbox.visibility = if (SP.getBoolean(R.string.key_usesuperbolus, false)) View.VISIBLE else View.GONE treatments_wizard_sbcheckbox.visibility = SP.getBoolean(R.string.key_usesuperbolus, false).toVisibility()
treatments_wizard_notes_layout.visibility = if (SP.getBoolean(R.string.key_show_notes_entry_dialogs, false)) View.VISIBLE else View.GONE treatments_wizard_notes_layout.visibility = SP.getBoolean(R.string.key_show_notes_entry_dialogs, false).toVisibility()
val maxCarbs = MainApp.getConstraintChecker().maxCarbsAllowed.value() val maxCarbs = MainApp.getConstraintChecker().maxCarbsAllowed.value()
val maxCorrection = MainApp.getConstraintChecker().maxBolusAllowed.value() val maxCorrection = MainApp.getConstraintChecker().maxBolusAllowed.value()
@ -115,7 +105,7 @@ class WizardDialog : DialogFragment() {
} else { } else {
okClicked = true okClicked = true
calculateInsulin() calculateInsulin()
parentContext?.let { context -> context?.let { context ->
wizard?.confirmAndExecute(context) wizard?.confirmAndExecute(context)
} }
} }
@ -124,23 +114,23 @@ class WizardDialog : DialogFragment() {
// cancel button // cancel button
cancel.setOnClickListener { dismiss() } cancel.setOnClickListener { dismiss() }
// checkboxes // checkboxes
treatments_wizard_bgcheckbox.setOnCheckedChangeListener { buttonView, _ -> onCheckedChanged(buttonView) } treatments_wizard_bgcheckbox.setOnCheckedChangeListener(::onCheckedChanged)
treatments_wizard_ttcheckbox.setOnCheckedChangeListener { buttonView, _ -> onCheckedChanged(buttonView) } treatments_wizard_ttcheckbox.setOnCheckedChangeListener(::onCheckedChanged)
treatments_wizard_cobcheckbox.setOnCheckedChangeListener { buttonView, _ -> onCheckedChanged(buttonView) } treatments_wizard_cobcheckbox.setOnCheckedChangeListener(::onCheckedChanged)
treatments_wizard_basaliobcheckbox.setOnCheckedChangeListener { buttonView, _ -> onCheckedChanged(buttonView) } treatments_wizard_basaliobcheckbox.setOnCheckedChangeListener(::onCheckedChanged)
treatments_wizard_bolusiobcheckbox.setOnCheckedChangeListener { buttonView, _ -> onCheckedChanged(buttonView) } treatments_wizard_bolusiobcheckbox.setOnCheckedChangeListener(::onCheckedChanged)
treatments_wizard_bgtrendcheckbox.setOnCheckedChangeListener { buttonView, _ -> onCheckedChanged(buttonView) } treatments_wizard_bgtrendcheckbox.setOnCheckedChangeListener(::onCheckedChanged)
treatments_wizard_sbcheckbox.setOnCheckedChangeListener { buttonView, _ -> onCheckedChanged(buttonView) } treatments_wizard_sbcheckbox.setOnCheckedChangeListener(::onCheckedChanged)
val showCalc = SP.getBoolean(MainApp.gs(R.string.key_wizard_calculation_visible), false) val showCalc = SP.getBoolean(MainApp.gs(R.string.key_wizard_calculation_visible), false)
treatments_wizard_delimiter.visibility = if (showCalc) View.VISIBLE else View.GONE treatments_wizard_delimiter.visibility = showCalc.toVisibility()
treatments_wizard_resulttable.visibility = if (showCalc) View.VISIBLE else View.GONE treatments_wizard_resulttable.visibility = showCalc.toVisibility()
treatments_wizard_calculationcheckbox.isChecked = showCalc treatments_wizard_calculationcheckbox.isChecked = showCalc
treatments_wizard_calculationcheckbox.setOnCheckedChangeListener { _, isChecked -> treatments_wizard_calculationcheckbox.setOnCheckedChangeListener { _, isChecked ->
run { run {
SP.putBoolean(MainApp.gs(R.string.key_wizard_calculation_visible), isChecked) SP.putBoolean(MainApp.gs(R.string.key_wizard_calculation_visible), isChecked)
treatments_wizard_delimiter.visibility = if (isChecked) View.VISIBLE else View.GONE treatments_wizard_delimiter.visibility = isChecked.toVisibility()
treatments_wizard_resulttable.visibility = if (isChecked) View.VISIBLE else View.GONE treatments_wizard_resulttable.visibility = isChecked.toVisibility()
} }
} }
// profile spinner // profile spinner
@ -173,7 +163,7 @@ class WizardDialog : DialogFragment() {
disposable.clear() disposable.clear()
} }
private fun onCheckedChanged(buttonView: CompoundButton) { private fun onCheckedChanged(buttonView: CompoundButton, @Suppress("UNUSED_PARAMETER") state: Boolean) {
saveCheckedStates() saveCheckedStates()
treatments_wizard_ttcheckbox.isEnabled = treatments_wizard_bgcheckbox.isChecked && TreatmentsPlugin.getPlugin().tempTargetFromHistory != null treatments_wizard_ttcheckbox.isEnabled = treatments_wizard_bgcheckbox.isChecked && TreatmentsPlugin.getPlugin().tempTargetFromHistory != null
if (buttonView.id == treatments_wizard_cobcheckbox.id) if (buttonView.id == treatments_wizard_cobcheckbox.id)
@ -204,7 +194,7 @@ class WizardDialog : DialogFragment() {
} }
private fun initDialog() { private fun initDialog() {
val profile = ProfileFunctions.getInstance().profile val profile = ProfileFunctions.getInstance().getProfile()
val profileStore = ConfigBuilderPlugin.getPlugin().activeProfileInterface?.profile val profileStore = ConfigBuilderPlugin.getPlugin().activeProfileInterface?.profile
if (profile == null || profileStore == null) { if (profile == null || profileStore == null) {
@ -221,7 +211,6 @@ class WizardDialog : DialogFragment() {
treatments_wizard_profile.adapter = adapter treatments_wizard_profile.adapter = adapter
} ?: return } ?: return
val units = ProfileFunctions.getSystemUnits() val units = ProfileFunctions.getSystemUnits()
treatments_wizard_bgunits.text = units treatments_wizard_bgunits.text = units
if (units == Constants.MGDL) if (units == Constants.MGDL)
@ -250,7 +239,7 @@ class WizardDialog : DialogFragment() {
calculateInsulin() calculateInsulin()
treatments_wizard_percent_used.visibility = if (SP.getInt(R.string.key_boluswizard_percentage, 100) != 100) View.VISIBLE else View.GONE treatments_wizard_percent_used.visibility = (SP.getInt(R.string.key_boluswizard_percentage, 100) != 100).toVisibility()
} }
private fun calculateInsulin() { private fun calculateInsulin() {
@ -260,8 +249,8 @@ class WizardDialog : DialogFragment() {
var profileName = treatments_wizard_profile.selectedItem.toString() var profileName = treatments_wizard_profile.selectedItem.toString()
val specificProfile: Profile? val specificProfile: Profile?
if (profileName == MainApp.gs(R.string.active)) { if (profileName == MainApp.gs(R.string.active)) {
specificProfile = ProfileFunctions.getInstance().profile specificProfile = ProfileFunctions.getInstance().getProfile()
profileName = ProfileFunctions.getInstance().profileName profileName = ProfileFunctions.getInstance().getProfileName() ?: return
} else } else
specificProfile = profileStore.getSpecificProfile(profileName) specificProfile = profileStore.getSpecificProfile(profileName)

View file

@ -4,7 +4,6 @@ import android.os.SystemClock;
import android.preference.Preference; import android.preference.Preference;
import android.preference.PreferenceFragment; import android.preference.PreferenceFragment;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentActivity;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -20,6 +19,7 @@ import info.nightscout.androidaps.plugins.bus.RxBus;
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.configBuilder.EventConfigBuilderUpdateGui; import info.nightscout.androidaps.plugins.configBuilder.EventConfigBuilderUpdateGui;
import info.nightscout.androidaps.queue.CommandQueue; import info.nightscout.androidaps.queue.CommandQueue;
import info.nightscout.androidaps.utils.OKDialog;
import info.nightscout.androidaps.utils.SP; import info.nightscout.androidaps.utils.SP;
/** /**
@ -58,20 +58,16 @@ public abstract class PluginBase {
if (allowHardwarePump || activity == null) { if (allowHardwarePump || activity == null) {
performPluginSwitch(newState, type); performPluginSwitch(newState, type);
} else { } else {
AlertDialog.Builder builder = new AlertDialog.Builder(activity); OKDialog.showConfirmation(activity, MainApp.gs(R.string.allow_hardware_pump_text), () -> {
builder.setMessage(R.string.allow_hardware_pump_text)
.setPositiveButton(R.string.yes, (dialog, id) -> {
performPluginSwitch(newState, type); performPluginSwitch(newState, type);
SP.putBoolean("allow_hardware_pump", true); SP.putBoolean("allow_hardware_pump", true);
if (L.isEnabled(L.PUMP)) if (L.isEnabled(L.PUMP))
log.debug("First time HW pump allowed!"); log.debug("First time HW pump allowed!");
}) }, () -> {
.setNegativeButton(R.string.cancel, (dialog, id) -> {
RxBus.INSTANCE.send(new EventConfigBuilderUpdateGui()); RxBus.INSTANCE.send(new EventConfigBuilderUpdateGui());
if (L.isEnabled(L.PUMP)) if (L.isEnabled(L.PUMP))
log.debug("User does not allow switching to HW pump!"); log.debug("User does not allow switching to HW pump!");
}); });
builder.create().show();
} }
} else { } else {
performPluginSwitch(newState, type); performPluginSwitch(newState, type);

View file

@ -381,13 +381,11 @@ public class DeviceStatus {
try { try {
if (device != null) record.put("device", device); if (device != null) record.put("device", device);
if (pump != null) record.put("pump", pump); if (pump != null) record.put("pump", pump);
if (suggested != null) {
JSONObject openaps = new JSONObject(); JSONObject openaps = new JSONObject();
if (enacted != null) openaps.put("enacted", enacted); if (enacted != null) openaps.put("enacted", enacted);
if (suggested != null) openaps.put("suggested", suggested); if (suggested != null) openaps.put("suggested", suggested);
if (iob != null) openaps.put("iob", iob); if (iob != null) openaps.put("iob", iob);
record.put("openaps", openaps); record.put("openaps", openaps);
}
if (uploaderBattery != 0) record.put("uploaderBattery", uploaderBattery); if (uploaderBattery != 0) record.put("uploaderBattery", uploaderBattery);
if (created_at != null) record.put("created_at", created_at); if (created_at != null) record.put("created_at", created_at);
} catch (JSONException e) { } catch (JSONException e) {

View file

@ -50,7 +50,7 @@ import info.nightscout.androidaps.plugins.bus.RxBus;
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload; import info.nightscout.androidaps.plugins.general.nsclient.NSUpload;
import info.nightscout.androidaps.plugins.general.overview.dialogs.ErrorHelperActivity; import info.nightscout.androidaps.activities.ErrorHelperActivity;
import info.nightscout.androidaps.plugins.general.wear.ActionStringHandler; import info.nightscout.androidaps.plugins.general.wear.ActionStringHandler;
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventAutosensCalculationFinished; import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventAutosensCalculationFinished;
import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin; import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin;
@ -60,7 +60,6 @@ import info.nightscout.androidaps.queue.commands.Command;
import info.nightscout.androidaps.utils.FabricPrivacy; import info.nightscout.androidaps.utils.FabricPrivacy;
import info.nightscout.androidaps.utils.SP; import info.nightscout.androidaps.utils.SP;
import info.nightscout.androidaps.utils.T; import info.nightscout.androidaps.utils.T;
import info.nightscout.androidaps.utils.ToastUtils;
import io.reactivex.disposables.CompositeDisposable; import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.schedulers.Schedulers; import io.reactivex.schedulers.Schedulers;

View file

@ -2,11 +2,16 @@ package info.nightscout.androidaps.plugins.configBuilder;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.util.ArrayList; import java.util.ArrayList;
import javax.inject.Inject;
import javax.inject.Singleton;
import dagger.Lazy;
import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R; import info.nightscout.androidaps.R;
import info.nightscout.androidaps.events.EventAppInitialized; import info.nightscout.androidaps.events.EventAppInitialized;
@ -22,6 +27,7 @@ import info.nightscout.androidaps.interfaces.SensitivityInterface;
import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.plugins.bus.RxBus; import info.nightscout.androidaps.plugins.bus.RxBus;
import info.nightscout.androidaps.plugins.insulin.InsulinOrefRapidActingPlugin; import info.nightscout.androidaps.plugins.insulin.InsulinOrefRapidActingPlugin;
import info.nightscout.androidaps.plugins.profile.local.LocalProfilePlugin;
import info.nightscout.androidaps.plugins.profile.ns.NSProfilePlugin; import info.nightscout.androidaps.plugins.profile.ns.NSProfilePlugin;
import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin; import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin;
import info.nightscout.androidaps.plugins.sensitivity.SensitivityOref0Plugin; import info.nightscout.androidaps.plugins.sensitivity.SensitivityOref0Plugin;
@ -31,14 +37,20 @@ import info.nightscout.androidaps.utils.SP;
/** /**
* Created by mike on 05.08.2016. * Created by mike on 05.08.2016.
*/ */
@Singleton
public class ConfigBuilderPlugin extends PluginBase { public class ConfigBuilderPlugin extends PluginBase {
private Logger log = LoggerFactory.getLogger(L.CONFIGBUILDER); private Logger log = LoggerFactory.getLogger(L.CONFIGBUILDER);
private static ConfigBuilderPlugin configBuilderPlugin; private static ConfigBuilderPlugin configBuilderPlugin;
/**
* @deprecated Use dagger to get an instance
*/
@Deprecated
static public ConfigBuilderPlugin getPlugin() { static public ConfigBuilderPlugin getPlugin() {
if (configBuilderPlugin == null) if (configBuilderPlugin == null)
configBuilderPlugin = new ConfigBuilderPlugin(); throw new IllegalStateException("Accessing ConfigBuilder before first instantiation");
return configBuilderPlugin; return configBuilderPlugin;
} }
@ -53,7 +65,20 @@ public class ConfigBuilderPlugin extends PluginBase {
private CommandQueue commandQueue = new CommandQueue(); private CommandQueue commandQueue = new CommandQueue();
public ConfigBuilderPlugin() { private Lazy<InsulinOrefRapidActingPlugin> insulinOrefRapidActingPlugin;
//TODO: inject
LocalProfilePlugin localProfilePlugin = LocalProfilePlugin.INSTANCE;
/*
* Written by Adrian:
* The ConfigBuilderPlugin.getPlugin() method is used at 333 places throughout the app.
* In order to make the transition to DI, while legacy code is still calling `getPlugin()`,
* I'd instantiate this plugin very very early on (first injected dependency in MainApp) and use
* Lazy dependencies in this constructor.
* */
@Inject
public ConfigBuilderPlugin(Lazy<InsulinOrefRapidActingPlugin> insulinOrefRapidActingPlugin) {
super(new PluginDescription() super(new PluginDescription()
.mainType(PluginType.GENERAL) .mainType(PluginType.GENERAL)
.fragmentClass(ConfigBuilderFragment.class.getName()) .fragmentClass(ConfigBuilderFragment.class.getName())
@ -64,6 +89,8 @@ public class ConfigBuilderPlugin extends PluginBase {
.shortName(R.string.configbuilder_shortname) .shortName(R.string.configbuilder_shortname)
.description(R.string.description_config_builder) .description(R.string.description_config_builder)
); );
this.insulinOrefRapidActingPlugin = insulinOrefRapidActingPlugin;
configBuilderPlugin = this; // TODO: only while transitioning to Dagger
} }
@Override @Override
@ -237,9 +264,10 @@ public class ConfigBuilderPlugin extends PluginBase {
return activeBgSource; return activeBgSource;
} }
@Nullable @NotNull
public ProfileInterface getActiveProfileInterface() { public ProfileInterface getActiveProfileInterface() {
return activeProfile; if (activeProfile != null) return activeProfile;
else return localProfilePlugin;
} }
@Nullable @Nullable
@ -290,8 +318,8 @@ public class ConfigBuilderPlugin extends PluginBase {
pluginsInCategory = MainApp.getSpecificPluginsList(PluginType.INSULIN); pluginsInCategory = MainApp.getSpecificPluginsList(PluginType.INSULIN);
activeInsulin = (InsulinInterface) getTheOneEnabledInArray(pluginsInCategory, PluginType.INSULIN); activeInsulin = (InsulinInterface) getTheOneEnabledInArray(pluginsInCategory, PluginType.INSULIN);
if (activeInsulin == null) { if (activeInsulin == null) {
activeInsulin = InsulinOrefRapidActingPlugin.getPlugin(); activeInsulin = insulinOrefRapidActingPlugin.get();
InsulinOrefRapidActingPlugin.getPlugin().setPluginEnabled(PluginType.INSULIN, true); insulinOrefRapidActingPlugin.get().setPluginEnabled(PluginType.INSULIN, true);
if (L.isEnabled(L.CONFIGBUILDER)) if (L.isEnabled(L.CONFIGBUILDER))
log.debug("Defaulting InsulinOrefRapidActingPlugin"); log.debug("Defaulting InsulinOrefRapidActingPlugin");
} }
@ -449,7 +477,7 @@ public class ConfigBuilderPlugin extends PluginBase {
if (type == PluginType.PUMP) if (type == PluginType.PUMP)
VirtualPumpPlugin.getPlugin().setPluginEnabled(type, true); VirtualPumpPlugin.getPlugin().setPluginEnabled(type, true);
else if (type == PluginType.INSULIN) else if (type == PluginType.INSULIN)
InsulinOrefRapidActingPlugin.getPlugin().setPluginEnabled(type, true); insulinOrefRapidActingPlugin.get().setPluginEnabled(type, true);
else if (type == PluginType.SENSITIVITY) else if (type == PluginType.SENSITIVITY)
SensitivityOref0Plugin.getPlugin().setPluginEnabled(type, true); SensitivityOref0Plugin.getPlugin().setPluginEnabled(type, true);
else if (type == PluginType.PROFILE) else if (type == PluginType.PROFILE)

View file

@ -2,7 +2,11 @@ package info.nightscout.androidaps.plugins.configBuilder
import android.content.Intent import android.content.Intent
import android.view.View import android.view.View
import android.widget.* import android.widget.CheckBox
import android.widget.ImageButton
import android.widget.LinearLayout
import android.widget.RadioButton
import android.widget.TextView
import info.nightscout.androidaps.R import info.nightscout.androidaps.R
import info.nightscout.androidaps.activities.PreferencesActivity import info.nightscout.androidaps.activities.PreferencesActivity
import info.nightscout.androidaps.events.EventRebuildTabs import info.nightscout.androidaps.events.EventRebuildTabs
@ -10,6 +14,7 @@ import info.nightscout.androidaps.interfaces.PluginBase
import info.nightscout.androidaps.interfaces.PluginType import info.nightscout.androidaps.interfaces.PluginType
import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.utils.PasswordProtection import info.nightscout.androidaps.utils.PasswordProtection
import info.nightscout.androidaps.utils.toVisibility
class PluginViewHolder internal constructor(private val fragment: ConfigBuilderFragment, class PluginViewHolder internal constructor(private val fragment: ConfigBuilderFragment,
private val pluginType: PluginType, private val pluginType: PluginType,
@ -56,8 +61,8 @@ class PluginViewHolder internal constructor(private val fragment: ConfigBuilderF
} }
fun update() { fun update() {
enabledExclusive.visibility = if (areMultipleSelectionsAllowed(pluginType)) View.GONE else View.VISIBLE enabledExclusive.visibility = areMultipleSelectionsAllowed(pluginType).not().toVisibility()
enabledInclusive.visibility = if (areMultipleSelectionsAllowed(pluginType)) View.VISIBLE else View.GONE enabledInclusive.visibility = areMultipleSelectionsAllowed(pluginType).toVisibility()
enabledExclusive.isChecked = plugin.isEnabled(pluginType) enabledExclusive.isChecked = plugin.isEnabled(pluginType)
enabledInclusive.isChecked = plugin.isEnabled(pluginType) enabledInclusive.isChecked = plugin.isEnabled(pluginType)
enabledInclusive.isEnabled = !plugin.pluginDescription.alwaysEnabled enabledInclusive.isEnabled = !plugin.pluginDescription.alwaysEnabled
@ -70,7 +75,7 @@ class PluginViewHolder internal constructor(private val fragment: ConfigBuilderF
pluginDescription.text = plugin.description pluginDescription.text = plugin.description
} }
pluginPreferences.visibility = if (plugin.preferencesId == -1 || !plugin.isEnabled(pluginType)) View.INVISIBLE else View.VISIBLE pluginPreferences.visibility = if (plugin.preferencesId == -1 || !plugin.isEnabled(pluginType)) View.INVISIBLE else View.VISIBLE
pluginVisibility.visibility = if (plugin.hasFragment()) View.VISIBLE else View.INVISIBLE pluginVisibility.visibility = plugin.hasFragment().toVisibility()
pluginVisibility.isEnabled = !(plugin.pluginDescription.neverVisible || plugin.pluginDescription.alwaysVisible) && plugin.isEnabled(pluginType) pluginVisibility.isEnabled = !(plugin.pluginDescription.neverVisible || plugin.pluginDescription.alwaysVisible) && plugin.isEnabled(pluginType)
pluginVisibility.isChecked = plugin.isFragmentVisible pluginVisibility.isChecked = plugin.isFragmentVisible
} }

View file

@ -0,0 +1,19 @@
package info.nightscout.androidaps.plugins.configBuilder
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.data.ProfileStore
import info.nightscout.androidaps.db.ProfileSwitch
interface ProfileFunction {
fun getProfileName(): String?
fun getProfileName(customized: Boolean): String
fun getProfileNameWithDuration(): String
fun getProfileName(time: Long, customized: Boolean, showRemainingTime: Boolean): String
fun isProfileValid(from: String): Boolean
fun getProfile(): Profile?
fun getUnits(): String
fun getProfile(time: Long): Profile?
fun prepareProfileSwitch(profileStore: ProfileStore, profileName: String, duration: Int, percentage: Int, timeShift: Int, date: Long): ProfileSwitch
fun doProfileSwitch(profileStore: ProfileStore, profileName: String, duration: Int, percentage: Int, timeShift: Int, date: Long)
fun doProfileSwitch(duration: Int, percentage: Int, timeShift: Int)
}

View file

@ -0,0 +1,80 @@
package info.nightscout.androidaps.plugins.configBuilder
import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.data.ProfileStore
import info.nightscout.androidaps.db.ProfileSwitch
import info.nightscout.androidaps.db.Source
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
import info.nightscout.androidaps.utils.sharedPreferences.SP
import java.security.spec.InvalidParameterSpecException
import javax.inject.Inject
import javax.inject.Singleton
class ProfileFunctionImplementation constructor(private val sp: SP) : ProfileFunction {
override fun getProfileName(): String =
getProfileName(System.currentTimeMillis(), customized = true, showRemainingTime = false)
override fun getProfileName(customized: Boolean): String =
getProfileName(System.currentTimeMillis(), customized, showRemainingTime = false)
override fun getProfileName(time: Long, customized: Boolean, showRemainingTime: Boolean): String =
ProfileFunctions.getInstance().getProfileName(time, customized, showRemainingTime)
override fun getProfileNameWithDuration(): String =
getProfileName(System.currentTimeMillis(), customized = true, showRemainingTime = true)
override fun isProfileValid(from: String): Boolean =
getProfile()?.isValid(from) ?: false
override fun getProfile(): Profile? {
return ProfileFunctions.getInstance().getProfile()
}
override fun getProfile(time: Long): Profile? =
getProfile(System.currentTimeMillis())
override fun getUnits(): String =
sp.getString(R.string.key_units, Constants.MGDL)
override fun prepareProfileSwitch(profileStore: ProfileStore, profileName: String, duration: Int, percentage: Int, timeShift: Int, date: Long): ProfileSwitch {
val profile = profileStore.getSpecificProfile(profileName)
?: throw InvalidParameterSpecException(profileName)
val profileSwitch = ProfileSwitch()
profileSwitch.date = date
profileSwitch.source = Source.USER
profileSwitch.profileName = profileName
profileSwitch.profileJson = profile.data.toString()
profileSwitch.profilePlugin = ConfigBuilderPlugin.getPlugin().activeProfileInterface::class.java.name
profileSwitch.durationInMinutes = duration
profileSwitch.isCPP = percentage != 100 || timeShift != 0
profileSwitch.timeshift = timeShift
profileSwitch.percentage = percentage
return profileSwitch
}
override fun doProfileSwitch(profileStore: ProfileStore, profileName: String, duration: Int, percentage: Int, timeShift: Int, date: Long) {
val profileSwitch = prepareProfileSwitch(profileStore, profileName, duration, percentage, timeShift, date)
TreatmentsPlugin.getPlugin().addToHistoryProfileSwitch(profileSwitch)
if (percentage == 90 && duration == 10)
sp.putBoolean(R.string.key_objectiveuseprofileswitch, true)
}
override fun doProfileSwitch(duration: Int, percentage: Int, timeShift: Int) {
getProfile()?.let {
val profileSwitch = ProfileSwitch()
profileSwitch.date = System.currentTimeMillis()
profileSwitch.source = Source.USER
profileSwitch.profileName = ProfileFunctions.getInstance().getProfileName(System.currentTimeMillis(), customized = false, showRemainingTime = false)
profileSwitch.profileJson = it.data.toString()
profileSwitch.profilePlugin = ConfigBuilderPlugin.getPlugin().activeProfileInterface::class.java.name
profileSwitch.durationInMinutes = duration
profileSwitch.isCPP = percentage != 100 || timeShift != 0
profileSwitch.timeshift = timeShift
profileSwitch.percentage = percentage
TreatmentsPlugin.getPlugin().addToHistoryProfileSwitch(profileSwitch)
}
}
}

View file

@ -7,6 +7,7 @@ import androidx.annotation.Nullable;
import com.google.firebase.analytics.FirebaseAnalytics; import com.google.firebase.analytics.FirebaseAnalytics;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -14,6 +15,7 @@ import info.nightscout.androidaps.BuildConfig;
import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.Constants;
import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R; import info.nightscout.androidaps.R;
import info.nightscout.androidaps.activities.ErrorHelperActivity;
import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.data.ProfileStore; import info.nightscout.androidaps.data.ProfileStore;
import info.nightscout.androidaps.db.ProfileSwitch; import info.nightscout.androidaps.db.ProfileSwitch;
@ -24,7 +26,6 @@ import info.nightscout.androidaps.interfaces.ProfileInterface;
import info.nightscout.androidaps.interfaces.TreatmentsInterface; import info.nightscout.androidaps.interfaces.TreatmentsInterface;
import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.plugins.bus.RxBus; import info.nightscout.androidaps.plugins.bus.RxBus;
import info.nightscout.androidaps.plugins.general.overview.dialogs.ErrorHelperActivity;
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin; import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
import info.nightscout.androidaps.queue.Callback; import info.nightscout.androidaps.queue.Callback;
import info.nightscout.androidaps.utils.DateUtil; import info.nightscout.androidaps.utils.DateUtil;
@ -33,7 +34,7 @@ import info.nightscout.androidaps.utils.SP;
import io.reactivex.disposables.CompositeDisposable; import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.schedulers.Schedulers; import io.reactivex.schedulers.Schedulers;
public class ProfileFunctions { public class ProfileFunctions implements ProfileFunction {
private static Logger log = LoggerFactory.getLogger(L.PROFILE); private static Logger log = LoggerFactory.getLogger(L.PROFILE);
private CompositeDisposable disposable = new CompositeDisposable(); private CompositeDisposable disposable = new CompositeDisposable();
@ -75,18 +76,22 @@ public class ProfileFunctions {
); );
} }
@NotNull
public String getProfileName() { public String getProfileName() {
return getProfileName(System.currentTimeMillis(), true, false); return getProfileName(System.currentTimeMillis(), true, false);
} }
@NotNull
public String getProfileName(boolean customized) { public String getProfileName(boolean customized) {
return getProfileName(System.currentTimeMillis(), customized, false); return getProfileName(System.currentTimeMillis(), customized, false);
} }
@NotNull
public String getProfileNameWithDuration() { public String getProfileNameWithDuration() {
return getProfileName(System.currentTimeMillis(), true, true); return getProfileName(System.currentTimeMillis(), true, true);
} }
@NotNull
public String getProfileName(long time, boolean customized, boolean showRemainingTime) { public String getProfileName(long time, boolean customized, boolean showRemainingTime) {
String profileName = MainApp.gs(R.string.noprofileselected); String profileName = MainApp.gs(R.string.noprofileselected);
@ -114,7 +119,7 @@ public class ProfileFunctions {
return profileName; return profileName;
} }
public boolean isProfileValid(String from) { public boolean isProfileValid(@NotNull String from) {
Profile profile = getProfile(); Profile profile = getProfile();
return profile != null && profile.isValid(from); return profile != null && profile.isValid(from);
} }
@ -124,6 +129,12 @@ public class ProfileFunctions {
return getProfile(System.currentTimeMillis()); return getProfile(System.currentTimeMillis());
} }
@NotNull
public String getUnits() {
return getSystemUnits();
}
@NotNull
public static String getSystemUnits() { public static String getSystemUnits() {
return SP.getString(R.string.key_units, Constants.MGDL); return SP.getString(R.string.key_units, Constants.MGDL);
} }
@ -156,7 +167,8 @@ public class ProfileFunctions {
return null; return null;
} }
public static ProfileSwitch prepareProfileSwitch(final ProfileStore profileStore, final String profileName, final int duration, final int percentage, final int timeshift, long date) { @NotNull
public ProfileSwitch prepareProfileSwitch(@NotNull final ProfileStore profileStore, @NotNull final String profileName, final int duration, final int percentage, final int timeShift, long date) {
ProfileSwitch profileSwitch = new ProfileSwitch(); ProfileSwitch profileSwitch = new ProfileSwitch();
profileSwitch.date = date; profileSwitch.date = date;
profileSwitch.source = Source.USER; profileSwitch.source = Source.USER;
@ -164,20 +176,20 @@ public class ProfileFunctions {
profileSwitch.profileJson = profileStore.getSpecificProfile(profileName).getData().toString(); profileSwitch.profileJson = profileStore.getSpecificProfile(profileName).getData().toString();
profileSwitch.profilePlugin = ConfigBuilderPlugin.getPlugin().getActiveProfileInterface().getClass().getName(); profileSwitch.profilePlugin = ConfigBuilderPlugin.getPlugin().getActiveProfileInterface().getClass().getName();
profileSwitch.durationInMinutes = duration; profileSwitch.durationInMinutes = duration;
profileSwitch.isCPP = percentage != 100 || timeshift != 0; profileSwitch.isCPP = percentage != 100 || timeShift != 0;
profileSwitch.timeshift = timeshift; profileSwitch.timeshift = timeShift;
profileSwitch.percentage = percentage; profileSwitch.percentage = percentage;
return profileSwitch; return profileSwitch;
} }
public static void doProfileSwitch(final ProfileStore profileStore, final String profileName, final int duration, final int percentage, final int timeshift) { public void doProfileSwitch(@NotNull final ProfileStore profileStore, @NotNull final String profileName, final int duration, final int percentage, final int timeShift, final long date) {
ProfileSwitch profileSwitch = prepareProfileSwitch(profileStore, profileName, duration, percentage, timeshift, System.currentTimeMillis()); ProfileSwitch profileSwitch = prepareProfileSwitch(profileStore, profileName, duration, percentage, timeShift, date);
TreatmentsPlugin.getPlugin().addToHistoryProfileSwitch(profileSwitch); TreatmentsPlugin.getPlugin().addToHistoryProfileSwitch(profileSwitch);
if (percentage == 90 && duration == 10) if (percentage == 90 && duration == 10)
SP.putBoolean(R.string.key_objectiveuseprofileswitch, true); SP.putBoolean(R.string.key_objectiveuseprofileswitch, true);
} }
public static void doProfileSwitch(final int duration, final int percentage, final int timeshift) { public void doProfileSwitch(final int duration, final int percentage, final int timeShift) {
ProfileSwitch profileSwitch = TreatmentsPlugin.getPlugin().getProfileSwitchFromHistory(System.currentTimeMillis()); ProfileSwitch profileSwitch = TreatmentsPlugin.getPlugin().getProfileSwitchFromHistory(System.currentTimeMillis());
if (profileSwitch != null) { if (profileSwitch != null) {
profileSwitch = new ProfileSwitch(); profileSwitch = new ProfileSwitch();
@ -187,8 +199,8 @@ public class ProfileFunctions {
profileSwitch.profileJson = getInstance().getProfile().getData().toString(); profileSwitch.profileJson = getInstance().getProfile().getData().toString();
profileSwitch.profilePlugin = ConfigBuilderPlugin.getPlugin().getActiveProfileInterface().getClass().getName(); profileSwitch.profilePlugin = ConfigBuilderPlugin.getPlugin().getActiveProfileInterface().getClass().getName();
profileSwitch.durationInMinutes = duration; profileSwitch.durationInMinutes = duration;
profileSwitch.isCPP = percentage != 100 || timeshift != 0; profileSwitch.isCPP = percentage != 100 || timeShift != 0;
profileSwitch.timeshift = timeshift; profileSwitch.timeshift = timeShift;
profileSwitch.percentage = percentage; profileSwitch.percentage = percentage;
TreatmentsPlugin.getPlugin().addToHistoryProfileSwitch(profileSwitch); TreatmentsPlugin.getPlugin().addToHistoryProfileSwitch(profileSwitch);
} else { } else {

View file

@ -285,11 +285,13 @@ class ObjectivesFragment : Fragment() {
}.start() }.start()
} }
holder.unStart.setOnClickListener { holder.unStart.setOnClickListener {
OKDialog.showConfirmation(activity, MainApp.gs(R.string.doyouwantresetstart)) { activity?.let { activity ->
OKDialog.showConfirmation(activity, MainApp.gs(R.string.objectives), MainApp.gs(R.string.doyouwantresetstart), Runnable {
objective.startedOn = 0 objective.startedOn = 0
scrollToCurrentObjective() scrollToCurrentObjective()
RxBus.send(EventObjectivesUpdateGui()) RxBus.send(EventObjectivesUpdateGui())
RxBus.send(EventSWUpdate(false)) RxBus.send(EventSWUpdate(false))
})
} }
} }
holder.unFinish.setOnClickListener { holder.unFinish.setOnClickListener {
@ -320,7 +322,6 @@ class ObjectivesFragment : Fragment() {
} }
} }
override fun getItemCount(): Int { override fun getItemCount(): Int {
return ObjectivesPlugin.objectives.size return ObjectivesPlugin.objectives.size
} }

View file

@ -122,9 +122,9 @@ object ObjectivesPlugin : PluginBase(PluginDescription()
SP.putLong("Objectives_" + "smb" + "_started", DateUtil.now()) SP.putLong("Objectives_" + "smb" + "_started", DateUtil.now())
SP.putLong("Objectives_" + "smb" + "_accomplished", DateUtil.now()) SP.putLong("Objectives_" + "smb" + "_accomplished", DateUtil.now())
setupObjectives() setupObjectives()
OKDialog.show(activity, "", MainApp.gs(R.string.codeaccepted), null) OKDialog.show(activity, MainApp.gs(R.string.objectives), MainApp.gs(R.string.codeaccepted))
} else { } else {
OKDialog.show(activity, "", MainApp.gs(R.string.codeinvalid), null) OKDialog.show(activity, MainApp.gs(R.string.objectives), MainApp.gs(R.string.codeinvalid))
} }
} }

View file

@ -14,7 +14,7 @@ import info.nightscout.androidaps.plugins.constraints.objectives.events.EventNtp
import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.FabricPrivacy
import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable import io.reactivex.disposables.CompositeDisposable
import kotlinx.android.synthetic.main.overview_bolusprogress_dialog.* import kotlinx.android.synthetic.main.dialog_bolusprogress.*
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory
class NtpProgressDialog : DialogFragment() { class NtpProgressDialog : DialogFragment() {
@ -33,16 +33,17 @@ class NtpProgressDialog : DialogFragment() {
state = savedInstanceState?.getString("state", DEFAULT_STATE) ?: DEFAULT_STATE state = savedInstanceState?.getString("state", DEFAULT_STATE) ?: DEFAULT_STATE
percent = savedInstanceState?.getInt("percent", 0) ?: 0 percent = savedInstanceState?.getInt("percent", 0) ?: 0
return inflater.inflate(R.layout.overview_bolusprogress_dialog, container, false) return inflater.inflate(R.layout.dialog_bolusprogress, container, false)
} }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
overview_bolusprogress_stop.setOnClickListener { dismiss() } overview_bolusprogress_stop.setOnClickListener { dismiss() }
overview_bolusprogress_status.setText(state) overview_bolusprogress_status.text = state
overview_bolusprogress_progressbar.setMax(100) overview_bolusprogress_progressbar.max = 100
overview_bolusprogress_progressbar.setProgress(percent) overview_bolusprogress_progressbar.progress = percent
overview_bolusprogress_stop.text = MainApp.gs(R.string.close) overview_bolusprogress_stop.text = MainApp.gs(R.string.close)
overview_bolusprogress_title.text = MainApp.gs(R.string.please_wait)
} }
override fun onResume() { override fun onResume() {

View file

@ -7,6 +7,7 @@ import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.LinearLayout import android.widget.LinearLayout
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import info.nightscout.androidaps.Config import info.nightscout.androidaps.Config
import info.nightscout.androidaps.MainApp import info.nightscout.androidaps.MainApp
@ -18,17 +19,25 @@ import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions
import info.nightscout.androidaps.plugins.general.actions.defs.CustomAction import info.nightscout.androidaps.plugins.general.actions.defs.CustomAction
import info.nightscout.androidaps.plugins.general.actions.dialogs.FillDialog import info.nightscout.androidaps.dialogs.CareDialog
import info.nightscout.androidaps.plugins.general.actions.dialogs.NewExtendedBolusDialog import info.nightscout.androidaps.dialogs.ExtendedBolusDialog
import info.nightscout.androidaps.plugins.general.actions.dialogs.NewTempBasalDialog import info.nightscout.androidaps.dialogs.FillDialog
import info.nightscout.androidaps.dialogs.TempBasalDialog
import info.nightscout.androidaps.plugins.general.careportal.CareportalFragment import info.nightscout.androidaps.plugins.general.careportal.CareportalFragment
import info.nightscout.androidaps.plugins.general.careportal.Dialogs.NewNSTreatmentDialog import info.nightscout.androidaps.activities.ErrorHelperActivity
import info.nightscout.androidaps.dialogs.ProfileSwitchDialog
import info.nightscout.androidaps.dialogs.TempTargetDialog
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
import info.nightscout.androidaps.queue.Callback import info.nightscout.androidaps.queue.Callback
import info.nightscout.androidaps.utils.* import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.SP
import info.nightscout.androidaps.utils.SingleClickButton
import info.nightscout.androidaps.utils.plusAssign
import info.nightscout.androidaps.utils.toVisibility
import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable import io.reactivex.disposables.CompositeDisposable
import kotlinx.android.synthetic.main.actions_fragment.* import kotlinx.android.synthetic.main.actions_fragment.*
import kotlinx.android.synthetic.main.careportal_stats_fragment.*
import java.util.* import java.util.*
class ActionsFragment : Fragment() { class ActionsFragment : Fragment() {
@ -47,39 +56,45 @@ class ActionsFragment : Fragment() {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
actions_profileswitch.setOnClickListener { actions_profileswitch.setOnClickListener {
val newDialog = NewNSTreatmentDialog() fragmentManager?.let { ProfileSwitchDialog().show(it, "Actions") }
val profileSwitch = CareportalFragment.PROFILESWITCH
profileSwitch.executeProfileSwitch = true
newDialog.setOptions(profileSwitch, R.string.careportal_profileswitch)
fragmentManager?.let { newDialog.show(it, "NewNSTreatmentDialog") }
} }
actions_temptarget.setOnClickListener { actions_temptarget.setOnClickListener {
val newTTDialog = NewNSTreatmentDialog() fragmentManager?.let { TempTargetDialog().show(it, "Actions") }
val temptarget = CareportalFragment.TEMPTARGET
temptarget.executeTempTarget = true
newTTDialog.setOptions(temptarget, R.string.careportal_temporarytarget)
fragmentManager?.let { newTTDialog.show(it, "NewNSTreatmentDialog") }
} }
actions_extendedbolus.setOnClickListener { actions_extendedbolus.setOnClickListener {
fragmentManager?.let { NewExtendedBolusDialog().show(it, "NewExtendedDialog") } fragmentManager?.let { ExtendedBolusDialog().show(it, "Actions") }
} }
actions_extendedbolus_cancel.setOnClickListener { actions_extendedbolus_cancel.setOnClickListener {
if (TreatmentsPlugin.getPlugin().isInHistoryExtendedBoluslInProgress) { if (TreatmentsPlugin.getPlugin().isInHistoryExtendedBoluslInProgress) {
ConfigBuilderPlugin.getPlugin().commandQueue.cancelExtended(object : Callback() { ConfigBuilderPlugin.getPlugin().commandQueue.cancelExtended(object : Callback() {
override fun run() { override fun run() {
if (!result.success) if (!result.success) {
ToastUtils.showToastInUiThread(MainApp.instance().applicationContext, MainApp.gs(R.string.extendedbolusdeliveryerror)) val i = Intent(MainApp.instance(), ErrorHelperActivity::class.java)
i.putExtra("soundid", R.raw.boluserror)
i.putExtra("status", result.comment)
i.putExtra("title", MainApp.gs(R.string.extendedbolusdeliveryerror))
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
MainApp.instance().startActivity(i)
}
} }
}) })
} }
} }
actions_settempbasal.setOnClickListener { fragmentManager?.let { NewTempBasalDialog().show(it, "NewTempDialog") } } actions_settempbasal.setOnClickListener {
fragmentManager?.let { TempBasalDialog().show(it, "Actions") }
}
actions_canceltempbasal.setOnClickListener { actions_canceltempbasal.setOnClickListener {
if (TreatmentsPlugin.getPlugin().isTempBasalInProgress) { if (TreatmentsPlugin.getPlugin().isTempBasalInProgress) {
ConfigBuilderPlugin.getPlugin().commandQueue.cancelTempBasal(true, object : Callback() { ConfigBuilderPlugin.getPlugin().commandQueue.cancelTempBasal(true, object : Callback() {
override fun run() { override fun run() {
if (!result.success) if (!result.success) {
ToastUtils.showToastInUiThread(MainApp.instance().applicationContext, MainApp.gs(R.string.tempbasaldeliveryerror)) val i = Intent(MainApp.instance(), ErrorHelperActivity::class.java)
i.putExtra("soundid", R.raw.boluserror)
i.putExtra("status", result.comment)
i.putExtra("title", MainApp.gs(R.string.tempbasaldeliveryerror))
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
MainApp.instance().startActivity(i)
}
} }
}) })
} }
@ -87,6 +102,15 @@ class ActionsFragment : Fragment() {
actions_fill.setOnClickListener { fragmentManager?.let { FillDialog().show(it, "FillDialog") } } actions_fill.setOnClickListener { fragmentManager?.let { FillDialog().show(it, "FillDialog") } }
actions_historybrowser.setOnClickListener { startActivity(Intent(context, HistoryBrowseActivity::class.java)) } actions_historybrowser.setOnClickListener { startActivity(Intent(context, HistoryBrowseActivity::class.java)) }
actions_tddstats.setOnClickListener { startActivity(Intent(context, TDDStatsActivity::class.java)) } actions_tddstats.setOnClickListener { startActivity(Intent(context, TDDStatsActivity::class.java)) }
actions_bgcheck.setOnClickListener {
fragmentManager?.let { CareDialog().setOptions(CareDialog.EventType.BGCHECK, R.string.careportal_bgcheck).show(it, "Actions") }
}
actions_cgmsensorinsert.setOnClickListener {
fragmentManager?.let { CareDialog().setOptions(CareDialog.EventType.SENSOR_INSERT, R.string.careportal_cgmsensorinsert).show(it, "Actions") }
}
actions_pumpbatterychange.setOnClickListener {
fragmentManager?.let { CareDialog().setOptions(CareDialog.EventType.BATTERY_CHANGE, R.string.careportal_pumpbatterychange).show(it, "Actions") }
}
SP.putBoolean(R.string.key_objectiveuseactions, true) SP.putBoolean(R.string.key_objectiveuseactions, true)
} }
@ -97,43 +121,27 @@ class ActionsFragment : Fragment() {
disposable += RxBus disposable += RxBus
.toObservable(EventInitializationChanged::class.java) .toObservable(EventInitializationChanged::class.java)
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe({ .subscribe({ updateGui() }, { FabricPrivacy.logException(it) })
updateGui()
}, {
FabricPrivacy.logException(it)
})
disposable += RxBus disposable += RxBus
.toObservable(EventRefreshOverview::class.java) .toObservable(EventRefreshOverview::class.java)
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe({ .subscribe({ updateGui() }, { FabricPrivacy.logException(it) })
updateGui()
}, {
FabricPrivacy.logException(it)
})
disposable += RxBus disposable += RxBus
.toObservable(EventExtendedBolusChange::class.java) .toObservable(EventExtendedBolusChange::class.java)
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe({ .subscribe({ updateGui() }, { FabricPrivacy.logException(it) })
updateGui()
}, {
FabricPrivacy.logException(it)
})
disposable += RxBus disposable += RxBus
.toObservable(EventTempBasalChange::class.java) .toObservable(EventTempBasalChange::class.java)
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe({ .subscribe({ updateGui() }, { FabricPrivacy.logException(it) })
updateGui()
}, {
FabricPrivacy.logException(it)
})
disposable += RxBus disposable += RxBus
.toObservable(EventCustomActionsChanged::class.java) .toObservable(EventCustomActionsChanged::class.java)
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe({ .subscribe({ updateGui() }, { FabricPrivacy.logException(it) })
updateGui() disposable += RxBus
}, { .toObservable(EventCareportalEventChange::class.java)
FabricPrivacy.logException(it) .observeOn(AndroidSchedulers.mainThread())
}) .subscribe({ updateGui() }, { FabricPrivacy.logException(it) })
updateGui() updateGui()
} }
@ -149,7 +157,7 @@ class ActionsFragment : Fragment() {
if (ConfigBuilderPlugin.getPlugin().activeProfileInterface?.profile != null) View.VISIBLE if (ConfigBuilderPlugin.getPlugin().activeProfileInterface?.profile != null) View.VISIBLE
else View.GONE else View.GONE
if (ProfileFunctions.getInstance().profile == null) { if (ProfileFunctions.getInstance().getProfile() == null) {
actions_temptarget?.visibility = View.GONE actions_temptarget?.visibility = View.GONE
actions_extendedbolus?.visibility = View.GONE actions_extendedbolus?.visibility = View.GONE
actions_extendedbolus_cancel?.visibility = View.GONE actions_extendedbolus_cancel?.visibility = View.GONE
@ -198,8 +206,11 @@ class ActionsFragment : Fragment() {
if (!pump.pumpDescription.isRefillingCapable || !pump.isInitialized || pump.isSuspended) View.GONE if (!pump.pumpDescription.isRefillingCapable || !pump.isInitialized || pump.isSuspended) View.GONE
else View.VISIBLE else View.VISIBLE
actions_temptarget?.visibility = if (!Config.APS) View.GONE else View.VISIBLE actions_temptarget?.visibility = Config.APS.toVisibility()
actions_tddstats?.visibility = if (!pump.pumpDescription.supportsTDDs) View.GONE else View.VISIBLE actions_tddstats?.visibility = pump.pumpDescription.supportsTDDs.toVisibility()
activity?.let { activity ->
CareportalFragment.updateAge(activity, careportal_sensorage, careportal_insulinage, careportal_canulaage, careportal_pbage)
}
checkPumpCustomActions() checkPumpCustomActions()
} }
@ -224,8 +235,7 @@ class ActionsFragment : Fragment() {
val action = this.pumpCustomActions[b.text.toString()] val action = this.pumpCustomActions[b.text.toString()]
ConfigBuilderPlugin.getPlugin().activePump!!.executeCustomAction(action!!.customActionType) ConfigBuilderPlugin.getPlugin().activePump!!.executeCustomAction(action!!.customActionType)
} }
val top = activity?.let { ContextCompat.getDrawable(it, customAction.iconResourceId) }
val top = resources.getDrawable(customAction.iconResourceId)
btn.setCompoundDrawablesWithIntrinsicBounds(null, top, null, null) btn.setCompoundDrawablesWithIntrinsicBounds(null, top, null, null)
action_buttons_layout?.addView(btn) action_buttons_layout?.addView(btn)

View file

@ -1,5 +1,6 @@
package info.nightscout.androidaps.plugins.general.actions package info.nightscout.androidaps.plugins.general.actions
import info.nightscout.androidaps.Config
import info.nightscout.androidaps.R import info.nightscout.androidaps.R
import info.nightscout.androidaps.interfaces.PluginBase import info.nightscout.androidaps.interfaces.PluginBase
import info.nightscout.androidaps.interfaces.PluginDescription import info.nightscout.androidaps.interfaces.PluginDescription
@ -8,6 +9,8 @@ import info.nightscout.androidaps.interfaces.PluginType
object ActionsPlugin : PluginBase(PluginDescription() object ActionsPlugin : PluginBase(PluginDescription()
.mainType(PluginType.GENERAL) .mainType(PluginType.GENERAL)
.fragmentClass(ActionsFragment::class.qualifiedName) .fragmentClass(ActionsFragment::class.qualifiedName)
.enableByDefault(Config.APS || Config.PUMPCONTROL)
.visibleByDefault(Config.APS || Config.PUMPCONTROL)
.pluginName(R.string.actions) .pluginName(R.string.actions)
.shortName(R.string.actions_shortname) .shortName(R.string.actions_shortname)
.description(R.string.description_actions)) .description(R.string.description_actions))

View file

@ -1,63 +0,0 @@
package info.nightscout.androidaps.plugins.general.actions.defs;
import info.nightscout.androidaps.R;
/**
* Created by andy on 9/20/18.
*/
public class CustomAction {
private int name;
private String iconName;
private CustomActionType customActionType;
private int iconResourceId;
private boolean enabled = true;
public CustomAction(int nameResourceId, CustomActionType actionType) {
this(nameResourceId, actionType, R.drawable.icon_actions_profileswitch, true);
}
public CustomAction(int nameResourceId, CustomActionType actionType, int iconResourceId) {
this(nameResourceId, actionType, iconResourceId, true);
}
public CustomAction(int nameResourceId, CustomActionType actionType, boolean enabled) {
this(nameResourceId, actionType, R.drawable.icon_actions_profileswitch, enabled);
}
public CustomAction(int nameResourceId, CustomActionType actionType, int iconResourceId, boolean enabled) {
this.name = nameResourceId;
this.customActionType = actionType;
this.iconResourceId = iconResourceId;
this.enabled = enabled;
}
public int getName() {
return name;
}
public CustomActionType getCustomActionType() {
return customActionType;
}
public int getIconResourceId() {
return iconResourceId;
}
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
}

View file

@ -0,0 +1,10 @@
package info.nightscout.androidaps.plugins.general.actions.defs
import info.nightscout.androidaps.R
class CustomAction @JvmOverloads constructor(val name: Int, val customActionType: CustomActionType?, val iconResourceId: Int = R.drawable.icon_actions_profileswitch, var isEnabled: Boolean = true) {
constructor(nameResourceId: Int, actionType: CustomActionType?, enabled: Boolean) :
this(nameResourceId, actionType, R.drawable.icon_actions_profileswitch, enabled)
}

View file

@ -1,11 +0,0 @@
package info.nightscout.androidaps.plugins.general.actions.defs;
/**
* Created by andy on 9/20/18.
*/
public interface CustomActionType {
String getKey();
}

View file

@ -0,0 +1,5 @@
package info.nightscout.androidaps.plugins.general.actions.defs
interface CustomActionType {
val key: String?
}

View file

@ -1,255 +0,0 @@
package info.nightscout.androidaps.plugins.general.actions.dialogs;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import androidx.fragment.app.DialogFragment;
import androidx.appcompat.app.AlertDialog;
import android.text.Editable;
import android.text.Html;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.LinearLayout;
import com.google.common.base.Joiner;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.LinkedList;
import java.util.List;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.DetailedBolusInfo;
import info.nightscout.androidaps.db.CareportalEvent;
import info.nightscout.androidaps.db.Source;
import info.nightscout.androidaps.interfaces.Constraint;
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload;
import info.nightscout.androidaps.plugins.general.overview.dialogs.ErrorHelperActivity;
import info.nightscout.androidaps.queue.Callback;
import info.nightscout.androidaps.utils.DecimalFormatter;
import info.nightscout.androidaps.utils.NumberPicker;
import info.nightscout.androidaps.utils.SP;
import info.nightscout.androidaps.utils.SafeParse;
import info.nightscout.androidaps.utils.ToastUtils;
import static info.nightscout.androidaps.utils.DateUtil.now;
public class FillDialog extends DialogFragment implements OnClickListener {
private static Logger log = LoggerFactory.getLogger(FillDialog.class);
private CheckBox pumpSiteChangeCheckbox;
private CheckBox insulinCartridgeChangeCheckbox;
private NumberPicker editInsulin;
double amount1 = 0d;
double amount2 = 0d;
double amount3 = 0d;
private EditText notesEdit;
//one shot guards
private boolean accepted;
private boolean okClicked;
final private TextWatcher textWatcher = new TextWatcher() {
@Override
public void afterTextChanged(Editable s) {
validateInputs();
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
};
private void validateInputs() {
int time = editInsulin.getValue().intValue();
if (Math.abs(time) > 12 * 60) {
editInsulin.setValue(0d);
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.constraintapllied));
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.actions_fill_dialog, container, false);
view.findViewById(R.id.ok).setOnClickListener(this);
view.findViewById(R.id.cancel).setOnClickListener(this);
getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
pumpSiteChangeCheckbox = view.findViewById(R.id.fill_catheter_change);
insulinCartridgeChangeCheckbox = view.findViewById(R.id.fill_cartridge_change);
Double maxInsulin = MainApp.getConstraintChecker().getMaxBolusAllowed().value();
double bolusstep = ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription().bolusStep;
editInsulin = view.findViewById(R.id.fill_insulinamount);
editInsulin.setParams(0d, 0d, maxInsulin, bolusstep, DecimalFormatter.pumpSupportedBolusFormat(), false, view.findViewById(R.id.ok), textWatcher);
Button preset1Button = view.findViewById(R.id.fill_preset_button1);
amount1 = SP.getDouble("fill_button1", 0.3);
if (amount1 > 0) {
preset1Button.setVisibility(View.VISIBLE);
preset1Button.setText(DecimalFormatter.toPumpSupportedBolus(amount1)); // + "U");
preset1Button.setOnClickListener(this);
} else {
preset1Button.setVisibility(View.GONE);
}
Button preset2Button = view.findViewById(R.id.fill_preset_button2);
amount2 = SP.getDouble("fill_button2", 0d);
if (amount2 > 0) {
preset2Button.setVisibility(View.VISIBLE);
preset2Button.setText(DecimalFormatter.toPumpSupportedBolus(amount2)); // + "U");
preset2Button.setOnClickListener(this);
} else {
preset2Button.setVisibility(View.GONE);
}
Button preset3Button = view.findViewById(R.id.fill_preset_button3);
amount3 = SP.getDouble("fill_button3", 0d);
if (amount3 > 0) {
preset3Button.setVisibility(View.VISIBLE);
preset3Button.setText(DecimalFormatter.toPumpSupportedBolus(amount3)); // + "U");
preset3Button.setOnClickListener(this);
} else {
preset3Button.setVisibility(View.GONE);
}
LinearLayout notesLayout = view.findViewById(R.id.fill_notes_layout);
notesLayout.setVisibility(SP.getBoolean(R.string.key_show_notes_entry_dialogs, false) ? View.VISIBLE : View.GONE);
notesEdit = view.findViewById(R.id.fill_notes);
setCancelable(true);
getDialog().setCanceledOnTouchOutside(false);
return view;
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.ok:
confirmAndDeliver();
break;
case R.id.cancel:
dismiss();
break;
case R.id.fill_preset_button1:
editInsulin.setValue(amount1);
break;
case R.id.fill_preset_button2:
editInsulin.setValue(amount2);
break;
case R.id.fill_preset_button3:
editInsulin.setValue(amount3);
break;
}
}
private synchronized void confirmAndDeliver() {
if (okClicked) {
log.debug("guarding: ok already clicked");
dismiss();
return;
}
okClicked = true;
try {
Double insulin = SafeParse.stringToDouble(editInsulin.getText());
List<String> confirmMessage = new LinkedList<>();
Double insulinAfterConstraints = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(insulin)).value();
if (insulinAfterConstraints > 0) {
confirmMessage.add(MainApp.gs(R.string.fillwarning));
confirmMessage.add("");
confirmMessage.add(MainApp.gs(R.string.bolus) + ": " + "<font color='" + MainApp.gc(R.color.colorCarbsButton) + "'>" + DecimalFormatter.toPumpSupportedBolus(insulinAfterConstraints) + "U" + "</font>");
if (Math.abs(insulinAfterConstraints - insulin) > 0.01d)
confirmMessage.add(MainApp.gs(R.string.bolusconstraintappliedwarning, MainApp.gc(R.color.warning), insulin, insulinAfterConstraints));
}
if (pumpSiteChangeCheckbox.isChecked())
confirmMessage.add("" + "<font color='" + MainApp.gc(R.color.actionsConfirm) + "'>" + MainApp.gs(R.string.record_pump_site_change) + "</font>");
if (insulinCartridgeChangeCheckbox.isChecked())
confirmMessage.add("" + "<font color='" + MainApp.gc(R.color.actionsConfirm) + "'>" + MainApp.gs(R.string.record_insulin_cartridge_change) + "</font>");
final String notes = notesEdit.getText().toString();
if (!notes.isEmpty()) {
confirmMessage.add(MainApp.gs(R.string.careportal_newnstreatment_notes_label) + ": " + notes);
}
final Double finalInsulinAfterConstraints = insulinAfterConstraints;
final Context context = getContext();
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(MainApp.gs(R.string.confirmation));
if (insulinAfterConstraints > 0 || pumpSiteChangeCheckbox.isChecked() || insulinCartridgeChangeCheckbox.isChecked()) {
builder.setMessage(Html.fromHtml(Joiner.on("<br/>").join(confirmMessage)));
builder.setPositiveButton(MainApp.gs(R.string.primefill), (dialog, id) -> {
synchronized (builder) {
if (accepted) {
log.debug("guarding: already accepted");
return;
}
accepted = true;
if (finalInsulinAfterConstraints > 0) {
DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo();
detailedBolusInfo.insulin = finalInsulinAfterConstraints;
detailedBolusInfo.context = context;
detailedBolusInfo.source = Source.USER;
detailedBolusInfo.isValid = false; // do not count it in IOB (for pump history)
detailedBolusInfo.notes = notes;
ConfigBuilderPlugin.getPlugin().getCommandQueue().bolus(detailedBolusInfo, new Callback() {
@Override
public void run() {
if (!result.success) {
Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class);
i.putExtra("soundid", R.raw.boluserror);
i.putExtra("status", result.comment);
i.putExtra("title", MainApp.gs(R.string.treatmentdeliveryerror));
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
MainApp.instance().startActivity(i);
}
}
});
}
if (pumpSiteChangeCheckbox.isChecked())
NSUpload.uploadEvent(CareportalEvent.SITECHANGE, now(), notes);
if (insulinCartridgeChangeCheckbox.isChecked())
NSUpload.uploadEvent(CareportalEvent.INSULINCHANGE, now() + 1000, notes);
}
});
} else {
builder.setMessage(MainApp.gs(R.string.no_action_selected));
}
builder.setNegativeButton(MainApp.gs(R.string.cancel), null);
builder.show();
dismiss();
} catch (RuntimeException e) {
log.error("Unhandled exception", e);
}
}
}

View file

@ -1,115 +0,0 @@
package info.nightscout.androidaps.plugins.general.actions.dialogs;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import androidx.fragment.app.DialogFragment;
import androidx.appcompat.app.AlertDialog;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.text.DecimalFormat;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.interfaces.Constraint;
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.general.overview.dialogs.ErrorHelperActivity;
import info.nightscout.androidaps.queue.Callback;
import info.nightscout.androidaps.utils.NumberPicker;
import info.nightscout.androidaps.utils.SafeParse;
public class NewExtendedBolusDialog extends DialogFragment implements View.OnClickListener {
private static Logger log = LoggerFactory.getLogger(NewExtendedBolusDialog.class);
NumberPicker editInsulin;
NumberPicker editDuration;
public NewExtendedBolusDialog() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
getDialog().setTitle(MainApp.gs(R.string.overview_extendedbolus_button));
View view = inflater.inflate(R.layout.overview_newextendedbolus_dialog, container, false);
Double maxInsulin = MainApp.getConstraintChecker().getMaxExtendedBolusAllowed().value();
editInsulin = (NumberPicker) view.findViewById(R.id.overview_newextendedbolus_insulin);
editInsulin.setParams(0d, 0d, maxInsulin, 0.1d, new DecimalFormat("0.00"), false, view.findViewById(R.id.ok));
double extendedDurationStep = ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription().extendedBolusDurationStep;
double extendedMaxDuration = ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription().extendedBolusMaxDuration;
editDuration = (NumberPicker) view.findViewById(R.id.overview_newextendedbolus_duration);
editDuration.setParams(extendedDurationStep, extendedDurationStep, extendedMaxDuration, extendedDurationStep, new DecimalFormat("0"), false, view.findViewById(R.id.ok));
view.findViewById(R.id.ok).setOnClickListener(this);
view.findViewById(R.id.cancel).setOnClickListener(this);
setCancelable(true);
getDialog().setCanceledOnTouchOutside(false);
return view;
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.ok:
try {
Double insulin = SafeParse.stringToDouble(editInsulin.getText());
int durationInMinutes = SafeParse.stringToInt(editDuration.getText());
String confirmMessage = MainApp.gs(R.string.setextendedbolusquestion);
Double insulinAfterConstraint = MainApp.getConstraintChecker().applyExtendedBolusConstraints(new Constraint<>(insulin)).value();
confirmMessage += " " + insulinAfterConstraint + " U ";
confirmMessage += MainApp.gs(R.string.duration) + " " + durationInMinutes + "min ?";
if (Math.abs(insulinAfterConstraint - insulin) > 0.01d)
confirmMessage += "\n" + MainApp.gs(R.string.constraintapllied);
insulin = insulinAfterConstraint;
final Double finalInsulin = insulin;
final int finalDurationInMinutes = durationInMinutes;
final Context context = getContext();
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(MainApp.gs(R.string.confirmation));
builder.setMessage(confirmMessage);
builder.setPositiveButton(MainApp.gs(R.string.ok), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
ConfigBuilderPlugin.getPlugin().getCommandQueue().extendedBolus(finalInsulin, finalDurationInMinutes, new Callback() {
@Override
public void run() {
if (!result.success) {
Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class);
i.putExtra("soundid", R.raw.boluserror);
i.putExtra("status", result.comment);
i.putExtra("title", MainApp.gs(R.string.treatmentdeliveryerror));
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
MainApp.instance().startActivity(i);
}
}
});
}
});
builder.setNegativeButton(MainApp.gs(R.string.cancel), null);
builder.show();
dismiss();
} catch (Exception e) {
log.error("Unhandled exception", e);
}
break;
case R.id.cancel:
dismiss();
break;
}
}
}

View file

@ -1,196 +0,0 @@
package info.nightscout.androidaps.plugins.general.actions.dialogs;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import androidx.fragment.app.DialogFragment;
import androidx.appcompat.app.AlertDialog;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.text.DecimalFormat;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.interfaces.Constraint;
import info.nightscout.androidaps.interfaces.PumpDescription;
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
import info.nightscout.androidaps.plugins.general.overview.dialogs.ErrorHelperActivity;
import info.nightscout.androidaps.queue.Callback;
import info.nightscout.androidaps.utils.NumberPicker;
import info.nightscout.androidaps.utils.SafeParse;
public class NewTempBasalDialog extends DialogFragment implements View.OnClickListener, RadioGroup.OnCheckedChangeListener {
private static Logger log = LoggerFactory.getLogger(NewTempBasalDialog.class);
RadioButton percentRadio;
RadioButton absoluteRadio;
RadioGroup basalTypeRadioGroup;
LinearLayout typeSelectorLayout;
LinearLayout percentLayout;
LinearLayout absoluteLayout;
NumberPicker basalPercent;
NumberPicker basalAbsolute;
NumberPicker duration;
public NewTempBasalDialog() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
getDialog().setTitle(MainApp.gs(R.string.overview_tempbasal_button));
View view = inflater.inflate(R.layout.overview_newtempbasal_dialog, container, false);
percentLayout = (LinearLayout) view.findViewById(R.id.overview_newtempbasal_percent_layout);
absoluteLayout = (LinearLayout) view.findViewById(R.id.overview_newtempbasal_absolute_layout);
percentRadio = (RadioButton) view.findViewById(R.id.overview_newtempbasal_percent_radio);
basalTypeRadioGroup = (RadioGroup) view.findViewById(R.id.overview_newtempbasal_radiogroup);
absoluteRadio = (RadioButton) view.findViewById(R.id.overview_newtempbasal_absolute_radio);
typeSelectorLayout = (LinearLayout) view.findViewById(R.id.overview_newtempbasal_typeselector_layout);
PumpDescription pumpDescription = ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription();
basalPercent = (NumberPicker) view.findViewById(R.id.overview_newtempbasal_basalpercentinput);
double maxTempPercent = pumpDescription.maxTempPercent;
double tempPercentStep = pumpDescription.tempPercentStep;
basalPercent.setParams(100d, 0d, maxTempPercent, tempPercentStep, new DecimalFormat("0"), true, view.findViewById(R.id.ok));
Profile profile = ProfileFunctions.getInstance().getProfile();
Double currentBasal = profile != null ? profile.getBasal() : 0d;
basalAbsolute = (NumberPicker) view.findViewById(R.id.overview_newtempbasal_basalabsoluteinput);
basalAbsolute.setParams(currentBasal, 0d, pumpDescription.maxTempAbsolute, pumpDescription.tempAbsoluteStep, new DecimalFormat("0.00"), true, view.findViewById(R.id.ok));
double tempDurationStep = pumpDescription.tempDurationStep;
double tempMaxDuration = pumpDescription.tempMaxDuration;
duration = (NumberPicker) view.findViewById(R.id.overview_newtempbasal_duration);
duration.setParams(tempDurationStep, tempDurationStep, tempMaxDuration, tempDurationStep, new DecimalFormat("0"), false, view.findViewById(R.id.ok));
if ((pumpDescription.tempBasalStyle & PumpDescription.PERCENT) == PumpDescription.PERCENT && (pumpDescription.tempBasalStyle & PumpDescription.ABSOLUTE) == PumpDescription.ABSOLUTE) {
// Both allowed
typeSelectorLayout.setVisibility(View.VISIBLE);
} else {
typeSelectorLayout.setVisibility(View.GONE);
}
if ((pumpDescription.tempBasalStyle & PumpDescription.PERCENT) == PumpDescription.PERCENT) {
percentRadio.setChecked(true);
absoluteRadio.setChecked(false);
percentLayout.setVisibility(View.VISIBLE);
absoluteLayout.setVisibility(View.GONE);
} else if ((pumpDescription.tempBasalStyle & PumpDescription.ABSOLUTE) == PumpDescription.ABSOLUTE) {
percentRadio.setChecked(false);
absoluteRadio.setChecked(true);
percentLayout.setVisibility(View.GONE);
absoluteLayout.setVisibility(View.VISIBLE);
}
view.findViewById(R.id.ok).setOnClickListener(this);
view.findViewById(R.id.cancel).setOnClickListener(this);
basalTypeRadioGroup.setOnCheckedChangeListener(this);
setCancelable(true);
getDialog().setCanceledOnTouchOutside(false);
return view;
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.ok:
try {
int percent = 0;
Double absolute = 0d;
final boolean setAsPercent = percentRadio.isChecked();
int durationInMinutes = SafeParse.stringToInt(duration.getText());
Profile profile = ProfileFunctions.getInstance().getProfile();
if (profile == null)
return;
String confirmMessage = MainApp.gs(R.string.setbasalquestion);
if (setAsPercent) {
int basalPercentInput = SafeParse.stringToInt(basalPercent.getText());
percent = MainApp.getConstraintChecker().applyBasalPercentConstraints(new Constraint<>(basalPercentInput), profile).value();
confirmMessage += "\n" + percent + "% ";
confirmMessage += "\n" + MainApp.gs(R.string.duration) + " " + durationInMinutes + "min ?";
if (percent != basalPercentInput)
confirmMessage += "\n" + MainApp.gs(R.string.constraintapllied);
} else {
Double basalAbsoluteInput = SafeParse.stringToDouble(basalAbsolute.getText());
absolute = MainApp.getConstraintChecker().applyBasalConstraints(new Constraint<>(basalAbsoluteInput), profile).value();
confirmMessage += "\n" + absolute + " U/h ";
confirmMessage += "\n" + MainApp.gs(R.string.duration) + " " + durationInMinutes + "min ?";
if (Math.abs(absolute - basalAbsoluteInput) > 0.01d)
confirmMessage += "\n" + MainApp.gs(R.string.constraintapllied);
}
final int finalBasalPercent = percent;
final Double finalBasal = absolute;
final int finalDurationInMinutes = durationInMinutes;
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setTitle(MainApp.gs(R.string.confirmation));
builder.setMessage(confirmMessage);
builder.setPositiveButton(MainApp.gs(R.string.ok), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
Callback callback = new Callback() {
@Override
public void run() {
if (!result.success) {
Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class);
i.putExtra("soundid", R.raw.boluserror);
i.putExtra("status", result.comment);
i.putExtra("title", MainApp.gs(R.string.tempbasaldeliveryerror));
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
MainApp.instance().startActivity(i);
}
}
};
if (setAsPercent) {
ConfigBuilderPlugin.getPlugin().getCommandQueue().tempBasalPercent(finalBasalPercent, finalDurationInMinutes, true, profile, callback);
} else {
ConfigBuilderPlugin.getPlugin().getCommandQueue().tempBasalAbsolute(finalBasal, finalDurationInMinutes, true, profile, callback);
}
}
});
builder.setNegativeButton(MainApp.gs(R.string.cancel), null);
builder.show();
dismiss();
} catch (Exception e) {
log.error("Unhandled exception", e);
}
break;
case R.id.cancel:
dismiss();
break;
}
}
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
switch (checkedId) {
case R.id.overview_newtempbasal_percent_radio:
percentLayout.setVisibility(View.VISIBLE);
absoluteLayout.setVisibility(View.GONE);
break;
case R.id.overview_newtempbasal_absolute_radio:
percentLayout.setVisibility(View.GONE);
absoluteLayout.setVisibility(View.VISIBLE);
break;
}
}
}

View file

@ -1,6 +1,7 @@
package info.nightscout.androidaps.plugins.general.automation package info.nightscout.androidaps.plugins.general.automation
import android.os.Bundle import android.os.Bundle
import android.text.method.ScrollingMovementMethod
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
@ -16,12 +17,12 @@ import info.nightscout.androidaps.plugins.general.automation.dragHelpers.SimpleI
import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationDataChanged import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationDataChanged
import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationUpdateGui import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationUpdateGui
import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.HtmlHelper
import info.nightscout.androidaps.utils.plusAssign import info.nightscout.androidaps.utils.plusAssign
import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable import io.reactivex.disposables.CompositeDisposable
import kotlinx.android.synthetic.main.automation_fragment.* import kotlinx.android.synthetic.main.automation_fragment.*
class AutomationFragment : Fragment(), OnStartDragListener { class AutomationFragment : Fragment(), OnStartDragListener {
private var disposable: CompositeDisposable = CompositeDisposable() private var disposable: CompositeDisposable = CompositeDisposable()
@ -40,6 +41,8 @@ class AutomationFragment : Fragment(), OnStartDragListener {
automation_eventListView.layoutManager = LinearLayoutManager(context) automation_eventListView.layoutManager = LinearLayoutManager(context)
automation_eventListView.adapter = eventListAdapter automation_eventListView.adapter = eventListAdapter
automation_logView.setMovementMethod(ScrollingMovementMethod())
automation_fabAddEvent.setOnClickListener { automation_fabAddEvent.setOnClickListener {
val dialog = EditEventDialog() val dialog = EditEventDialog()
val args = Bundle() val args = Bundle()
@ -88,8 +91,8 @@ class AutomationFragment : Fragment(), OnStartDragListener {
eventListAdapter?.notifyDataSetChanged() eventListAdapter?.notifyDataSetChanged()
val sb = StringBuilder() val sb = StringBuilder()
for (l in AutomationPlugin.executionLog.reversed()) for (l in AutomationPlugin.executionLog.reversed())
sb.append(l).append("\n") sb.append(l).append("<br>")
automation_logView?.text = sb.toString() automation_logView?.text = HtmlHelper.fromHtml(sb.toString())
} }
override fun onStartDrag(viewHolder: RecyclerView.ViewHolder) { override fun onStartDrag(viewHolder: RecyclerView.ViewHolder) {

View file

@ -178,10 +178,10 @@ object AutomationPlugin : PluginBase(PluginDescription()
val sb = StringBuilder() val sb = StringBuilder()
sb.append(DateUtil.timeString(DateUtil.now())) sb.append(DateUtil.timeString(DateUtil.now()))
sb.append(" ") sb.append(" ")
sb.append(if (result.success) "" else "X") sb.append(if (result.success) "" else "")
sb.append(" ") sb.append(" <b>")
sb.append(event.title) sb.append(event.title)
sb.append(": ") sb.append(":</b> ")
sb.append(action.shortDescription()) sb.append(action.shortDescription())
sb.append(": ") sb.append(": ")
sb.append(result.comment) sb.append(result.comment)

View file

@ -21,17 +21,29 @@ import info.nightscout.androidaps.plugins.general.automation.elements.InputProfi
import info.nightscout.androidaps.plugins.general.automation.elements.LabelWithElement; import info.nightscout.androidaps.plugins.general.automation.elements.LabelWithElement;
import info.nightscout.androidaps.plugins.general.automation.elements.LayoutBuilder; import info.nightscout.androidaps.plugins.general.automation.elements.LayoutBuilder;
import info.nightscout.androidaps.queue.Callback; import info.nightscout.androidaps.queue.Callback;
import info.nightscout.androidaps.utils.DateUtil;
import info.nightscout.androidaps.utils.JsonHelper; import info.nightscout.androidaps.utils.JsonHelper;
public class ActionProfileSwitch extends Action { public class ActionProfileSwitch extends Action {
private static Logger log = LoggerFactory.getLogger(L.AUTOMATION); private static Logger log = LoggerFactory.getLogger(L.AUTOMATION);
public InputProfileName inputProfileName = new InputProfileName(ProfileFunctions.getInstance().getProfileName()); InputProfileName inputProfileName;
String profileName = ""; String profileName = "";
public ActionProfileSwitch() { public ActionProfileSwitch() {
// Prevent action if active profile is already active // Prevent action if active profile is already active
// but we don't have a trigger IS_NOT_EQUAL // but we don't have a trigger IS_NOT_EQUAL
// so check is in the doRun() // so check is in the doRun()
ProfileInterface profileInterface = ConfigBuilderPlugin.getPlugin().getActiveProfileInterface();
if (profileInterface != null) {
ProfileStore profileStore = profileInterface.getProfile();
if (profileStore != null) {
String name = profileStore.getDefaultProfileName();
if (name != null) {
profileName = name;
}
}
}
inputProfileName = new InputProfileName(profileName);
} }
@Override @Override
@ -50,23 +62,43 @@ public class ActionProfileSwitch extends Action {
String activeProfileName = ProfileFunctions.getInstance().getProfileName(); String activeProfileName = ProfileFunctions.getInstance().getProfileName();
//Check for uninitialized profileName //Check for uninitialized profileName
if ( profileName.equals("")){ profileName = activeProfileName; } if ( profileName.equals("")){
log.error("Selected profile not initialized");
if (callback != null)
callback.result(new PumpEnactResult().success(false).comment(R.string.error_field_must_not_be_empty)).run();
return;
}
if ( ProfileFunctions.getInstance().getProfile() == null){
log.error("ProfileFunctions not initialized");
if (callback != null)
callback.result(new PumpEnactResult().success(false).comment(R.string.noprofile)).run();
return;
}
if (profileName.equals(activeProfileName)) { if (profileName.equals(activeProfileName)) {
// Profile is already switched if (L.isEnabled(L.AUTOMATION))
log.debug("Profile is already switched");
if (callback != null)
callback.result(new PumpEnactResult().success(true).comment(R.string.alreadyset)).run();
return; return;
} }
ProfileInterface activeProfile = ConfigBuilderPlugin.getPlugin().getActiveProfileInterface(); ProfileInterface activeProfile = ConfigBuilderPlugin.getPlugin().getActiveProfileInterface();
if (activeProfile == null) return; if (activeProfile == null) {
log.error("ProfileInterface not initialized");
if (callback != null)
callback.result(new PumpEnactResult().success(false).comment(R.string.noprofile)).run();
return;
}
ProfileStore profileStore = activeProfile.getProfile(); ProfileStore profileStore = activeProfile.getProfile();
if (profileStore == null) return; if (profileStore == null) return;
if(profileStore.getSpecificProfile(profileName) == null) { if(profileStore.getSpecificProfile(profileName) == null) {
if (L.isEnabled(L.AUTOMATION)) if (L.isEnabled(L.AUTOMATION))
log.error("Selected profile does not exist! - "+ profileName); log.error("Selected profile does not exist! - "+ profileName);
if (callback != null)
callback.result(new PumpEnactResult().success(false).comment(R.string.notexists)).run();
return; return;
} }
ProfileFunctions.doProfileSwitch(profileStore, profileName, 0, 100, 0); ProfileFunctions.getInstance().doProfileSwitch(profileStore, profileName, 0, 100, 0, DateUtil.now());
if (callback != null) if (callback != null)
callback.result(new PumpEnactResult().success(true).comment(R.string.ok)).run(); callback.result(new PumpEnactResult().success(true).comment(R.string.ok)).run();
} }

View file

@ -47,7 +47,7 @@ public class ActionProfileSwitchPercent extends Action {
@Override @Override
public void doAction(Callback callback) { public void doAction(Callback callback) {
ProfileFunctions.doProfileSwitch((int) duration.getValue(), (int) pct.getValue(), 0); ProfileFunctions.getInstance().doProfileSwitch((int) duration.getValue(), (int) pct.getValue(), 0);
if (callback != null) if (callback != null)
callback.result(new PumpEnactResult().success(true).comment(R.string.ok)).run(); callback.result(new PumpEnactResult().success(true).comment(R.string.ok)).run();
} }

View file

@ -9,10 +9,11 @@ import org.json.JSONObject;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R; import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.PumpEnactResult; import info.nightscout.androidaps.data.PumpEnactResult;
import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.plugins.general.automation.elements.InputString; import info.nightscout.androidaps.plugins.general.automation.elements.InputString;
import info.nightscout.androidaps.plugins.general.automation.elements.LabelWithElement; import info.nightscout.androidaps.plugins.general.automation.elements.LabelWithElement;
import info.nightscout.androidaps.plugins.general.automation.elements.LayoutBuilder; import info.nightscout.androidaps.plugins.general.automation.elements.LayoutBuilder;
@ -25,6 +26,14 @@ public class ActionSendSMS extends Action {
public InputString text = new InputString(); public InputString text = new InputString();
@Inject
SmsCommunicatorPlugin smsCommunicatorPlugin;
public ActionSendSMS() {
super();
MainApp.instance().androidInjector().inject(this); // TODO inject or pass itno constructor once AutomationPlugin is prepared for Dagger
}
@Override @Override
public int friendlyName() { public int friendlyName() {
return R.string.sendsmsactiondescription; return R.string.sendsmsactiondescription;
@ -37,7 +46,7 @@ public class ActionSendSMS extends Action {
@Override @Override
public void doAction(Callback callback) { public void doAction(Callback callback) {
boolean result = SmsCommunicatorPlugin.INSTANCE.sendNotificationToAllNumbers(text.getValue()); boolean result = smsCommunicatorPlugin.sendNotificationToAllNumbers(text.getValue());
if (callback != null) if (callback != null)
callback.result(new PumpEnactResult().success(result).comment(result ? R.string.ok : R.string.danar_error)).run(); callback.result(new PumpEnactResult().success(result).comment(result ? R.string.ok : R.string.danar_error)).run();

View file

@ -75,7 +75,7 @@ public class ActionStartTempTarget extends Action {
int unitResId = value.getUnits().equals(Constants.MGDL) ? R.string.mgdl : R.string.mmol; int unitResId = value.getUnits().equals(Constants.MGDL) ? R.string.mgdl : R.string.mmol;
new LayoutBuilder() new LayoutBuilder()
.add(new LabelWithElement(MainApp.gs(R.string.careportal_temporarytarget) + " [" + MainApp.gs(unitResId) + "]", "", value)) .add(new LabelWithElement(MainApp.gs(R.string.careportal_temporarytarget) + "\n[" + MainApp.gs(unitResId) + "]", "", value))
.add(new LabelWithElement(MainApp.gs(R.string.careportal_newnstreatment_duration_min_label), "", duration)) .add(new LabelWithElement(MainApp.gs(R.string.careportal_newnstreatment_duration_min_label), "", duration))
.build(root); .build(root);
} }

View file

@ -32,7 +32,7 @@ class ActionListAdapter(private val fragmentManager: FragmentManager, private va
class ViewHolder(val view: View) : RecyclerView.ViewHolder(view) { class ViewHolder(val view: View) : RecyclerView.ViewHolder(view) {
fun bind(action: Action, fragmentManager: FragmentManager, recyclerView: RecyclerView.Adapter<ViewHolder>, position : Int, actionList: MutableList<Action>) { fun bind(action: Action, fragmentManager: FragmentManager, recyclerView: RecyclerView.Adapter<ViewHolder>, position: Int, actionList: MutableList<Action>) {
view.findViewById<LinearLayout>(R.id.automation_layoutText).setOnClickListener { view.findViewById<LinearLayout>(R.id.automation_layoutText).setOnClickListener {
if (action.hasDialog()) { if (action.hasDialog()) {
val args = Bundle() val args = Bundle()
@ -48,6 +48,7 @@ class ActionListAdapter(private val fragmentManager: FragmentManager, private va
recyclerView.notifyDataSetChanged() recyclerView.notifyDataSetChanged()
RxBus.send(EventAutomationUpdateGui()) RxBus.send(EventAutomationUpdateGui())
} }
if (action.icon().isPresent) view.findViewById<ImageView>(R.id.automation_action_image).setImageResource(action.icon().get())
view.findViewById<TextView>(R.id.automation_viewActionTitle).text = action.shortDescription() view.findViewById<TextView>(R.id.automation_viewActionTitle).text = action.shortDescription()
} }
} }

View file

@ -5,19 +5,18 @@ import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.RadioButton import android.widget.RadioButton
import androidx.fragment.app.DialogFragment
import info.nightscout.androidaps.R import info.nightscout.androidaps.R
import info.nightscout.androidaps.dialogs.DialogFragmentWithDate
import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.plugins.general.automation.AutomationPlugin import info.nightscout.androidaps.plugins.general.automation.AutomationPlugin
import info.nightscout.androidaps.plugins.general.automation.actions.Action import info.nightscout.androidaps.plugins.general.automation.actions.Action
import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationAddAction import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationAddAction
import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationUpdateGui import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationUpdateGui
import kotlinx.android.synthetic.main.automation_dialog_choose_action.* import kotlinx.android.synthetic.main.automation_dialog_choose_action.*
import kotlinx.android.synthetic.main.okcancel.*
class ChooseActionDialog : DialogFragment() { class ChooseActionDialog : DialogFragmentWithDate() {
var checkedIndex = -1 private var checkedIndex = -1
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? { savedInstanceState: Bundle?): View? {
@ -26,7 +25,7 @@ class ChooseActionDialog : DialogFragment() {
checkedIndex = bundle.getInt("checkedIndex") checkedIndex = bundle.getInt("checkedIndex")
} }
dialog?.setCanceledOnTouchOutside(false) onCreateViewGeneral()
return inflater.inflate(R.layout.automation_dialog_choose_action, container, false) return inflater.inflate(R.layout.automation_dialog_choose_action, container, false)
} }
@ -42,27 +41,19 @@ class ChooseActionDialog : DialogFragment() {
if (checkedIndex != -1) if (checkedIndex != -1)
(automation_radioGroup.getChildAt(checkedIndex) as RadioButton).isChecked = true (automation_radioGroup.getChildAt(checkedIndex) as RadioButton).isChecked = true
}
// OK button override fun submit(): Boolean {
ok.setOnClickListener {
dismiss()
instantiateAction()?.let { instantiateAction()?.let {
RxBus.send(EventAutomationAddAction(it)) RxBus.send(EventAutomationAddAction(it))
RxBus.send(EventAutomationUpdateGui()) RxBus.send(EventAutomationUpdateGui())
} }
return true
} }
// Cancel button override fun onSaveInstanceState(savedInstanceState: Bundle) {
cancel.setOnClickListener { dismiss() } super.onSaveInstanceState(savedInstanceState)
} savedInstanceState.putInt("checkedIndex", determineCheckedIndex())
override fun onStart() {
super.onStart()
dialog?.window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
}
override fun onSaveInstanceState(bundle: Bundle) {
bundle.putInt("checkedIndex", determineCheckedIndex())
} }
private fun instantiateAction(): Action? { private fun instantiateAction(): Action? {
@ -86,5 +77,4 @@ class ChooseActionDialog : DialogFragment() {
} }
return -1 return -1
} }
} }

View file

@ -5,17 +5,15 @@ import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.RadioButton import android.widget.RadioButton
import androidx.fragment.app.DialogFragment
import info.nightscout.androidaps.R import info.nightscout.androidaps.R
import info.nightscout.androidaps.dialogs.DialogFragmentWithDate
import info.nightscout.androidaps.plugins.general.automation.AutomationPlugin import info.nightscout.androidaps.plugins.general.automation.AutomationPlugin
import info.nightscout.androidaps.plugins.general.automation.triggers.Trigger import info.nightscout.androidaps.plugins.general.automation.triggers.Trigger
import kotlinx.android.synthetic.main.automation_dialog_choose_trigger.* import kotlinx.android.synthetic.main.automation_dialog_choose_trigger.*
import kotlinx.android.synthetic.main.okcancel.*
class ChooseTriggerDialog : DialogFragment() { class ChooseTriggerDialog : DialogFragmentWithDate() {
private var checkedIndex = -1 private var checkedIndex = -1
private var clickListener: OnClickListener? = null private var clickListener: OnClickListener? = null
interface OnClickListener { interface OnClickListener {
@ -29,7 +27,7 @@ class ChooseTriggerDialog : DialogFragment() {
checkedIndex = bundle.getInt("checkedIndex") checkedIndex = bundle.getInt("checkedIndex")
} }
dialog?.setCanceledOnTouchOutside(false) onCreateViewGeneral()
return inflater.inflate(R.layout.automation_dialog_choose_trigger, container, false) return inflater.inflate(R.layout.automation_dialog_choose_trigger, container, false)
} }
@ -45,30 +43,22 @@ class ChooseTriggerDialog : DialogFragment() {
if (checkedIndex != -1) if (checkedIndex != -1)
(automation_chooseTriggerRadioGroup.getChildAt(checkedIndex) as RadioButton).isChecked = true (automation_chooseTriggerRadioGroup.getChildAt(checkedIndex) as RadioButton).isChecked = true
}
// OK button override fun submit(): Boolean {
ok.setOnClickListener {
dismiss()
instantiateTrigger()?.let { instantiateTrigger()?.let {
clickListener?.onClick(it) clickListener?.onClick(it)
} }
} return true
// Cancel button
cancel.setOnClickListener { dismiss() }
}
override fun onStart() {
super.onStart()
dialog?.window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
} }
fun setOnClickListener(clickListener: OnClickListener) { fun setOnClickListener(clickListener: OnClickListener) {
this.clickListener = clickListener this.clickListener = clickListener
} }
override fun onSaveInstanceState(bundle: Bundle) { override fun onSaveInstanceState(savedInstanceState: Bundle) {
bundle.putInt("checkedIndex", determineCheckedIndex()) super.onSaveInstanceState(savedInstanceState)
savedInstanceState.putInt("checkedIndex", determineCheckedIndex())
} }
private fun instantiateTrigger(): Trigger? { private fun instantiateTrigger(): Trigger? {
@ -92,5 +82,4 @@ class ChooseTriggerDialog : DialogFragment() {
} }
return -1 return -1
} }
} }

View file

@ -4,16 +4,15 @@ import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.fragment.app.DialogFragment
import info.nightscout.androidaps.R import info.nightscout.androidaps.R
import info.nightscout.androidaps.dialogs.DialogFragmentWithDate
import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.plugins.general.automation.actions.Action import info.nightscout.androidaps.plugins.general.automation.actions.Action
import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationUpdateAction import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationUpdateAction
import kotlinx.android.synthetic.main.automation_dialog_action.* import kotlinx.android.synthetic.main.automation_dialog_action.*
import kotlinx.android.synthetic.main.okcancel.*
import org.json.JSONObject import org.json.JSONObject
class EditActionDialog : DialogFragment() { class EditActionDialog : DialogFragmentWithDate() {
private var action: Action? = null private var action: Action? = null
private var actionPosition: Int = -1 private var actionPosition: Int = -1
@ -24,8 +23,7 @@ class EditActionDialog : DialogFragment() {
actionPosition = bundle.getInt("actionPosition", -1) actionPosition = bundle.getInt("actionPosition", -1)
bundle.getString("action")?.let { action = Action.instantiate(JSONObject(it)) } bundle.getString("action")?.let { action = Action.instantiate(JSONObject(it)) }
} }
onCreateViewGeneral()
dialog?.setCanceledOnTouchOutside(false)
return inflater.inflate(R.layout.automation_dialog_action, container, false) return inflater.inflate(R.layout.automation_dialog_action, container, false)
} }
@ -37,29 +35,20 @@ class EditActionDialog : DialogFragment() {
automation_editActionLayout.removeAllViews() automation_editActionLayout.removeAllViews()
it.generateDialog(automation_editActionLayout) it.generateDialog(automation_editActionLayout)
} }
}
// OK button override fun submit(): Boolean {
ok.setOnClickListener {
dismiss()
action?.let { action?.let {
RxBus.send(EventAutomationUpdateAction(it, actionPosition)) RxBus.send(EventAutomationUpdateAction(it, actionPosition))
} }
return true
} }
// Cancel button override fun onSaveInstanceState(savedInstanceState: Bundle) {
cancel.setOnClickListener { dismiss() } super.onSaveInstanceState(savedInstanceState)
}
override fun onStart() {
super.onStart()
dialog?.window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
}
override fun onSaveInstanceState(bundle: Bundle) {
super.onSaveInstanceState(bundle)
action?.let { action?.let {
bundle.putInt("actionPosition", actionPosition) savedInstanceState.putInt("actionPosition", actionPosition)
bundle.putString("action", it.toJSON()) savedInstanceState.putString("action", it.toJSON())
} }
} }
} }

View file

@ -4,9 +4,9 @@ import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.fragment.app.DialogFragment
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import info.nightscout.androidaps.R import info.nightscout.androidaps.R
import info.nightscout.androidaps.dialogs.DialogFragmentWithDate
import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.plugins.general.automation.AutomationEvent import info.nightscout.androidaps.plugins.general.automation.AutomationEvent
import info.nightscout.androidaps.plugins.general.automation.AutomationPlugin import info.nightscout.androidaps.plugins.general.automation.AutomationPlugin
@ -17,9 +17,8 @@ import info.nightscout.androidaps.utils.ToastUtils
import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable import io.reactivex.disposables.CompositeDisposable
import kotlinx.android.synthetic.main.automation_dialog_event.* import kotlinx.android.synthetic.main.automation_dialog_event.*
import kotlinx.android.synthetic.main.okcancel.*
class EditEventDialog : DialogFragment() { class EditEventDialog : DialogFragmentWithDate() {
private var actionListAdapter: ActionListAdapter? = null private var actionListAdapter: ActionListAdapter? = null
private var event: AutomationEvent = AutomationEvent() private var event: AutomationEvent = AutomationEvent()
@ -35,7 +34,7 @@ class EditEventDialog : DialogFragment() {
bundle.getString("event")?.let { event = AutomationEvent().fromJSON(it) } bundle.getString("event")?.let { event = AutomationEvent().fromJSON(it) }
} }
dialog?.setCanceledOnTouchOutside(false) onCreateViewGeneral()
return inflater.inflate(R.layout.automation_dialog_event, container, false) return inflater.inflate(R.layout.automation_dialog_event, container, false)
} }
@ -60,39 +59,6 @@ class EditEventDialog : DialogFragment() {
automation_addAction.setOnClickListener { fragmentManager?.let { ChooseActionDialog().show(it, "ChooseActionDialog") } } automation_addAction.setOnClickListener { fragmentManager?.let { ChooseActionDialog().show(it, "ChooseActionDialog") } }
// OK button
ok.setOnClickListener {
// check for title
val title = automation_inputEventTitle.text.toString()
if (title.isEmpty()) {
ToastUtils.showToastInUiThread(context, R.string.automation_missing_task_name)
return@setOnClickListener
}
event.title = title
// check for at least one trigger
val con = event.trigger as TriggerConnector
if (con.size() == 0) {
ToastUtils.showToastInUiThread(context, R.string.automation_missing_trigger)
return@setOnClickListener
}
// check for at least one action
if (event.actions.isEmpty()) {
ToastUtils.showToastInUiThread(context, R.string.automation_missing_action)
return@setOnClickListener
}
// store
if (position == -1)
AutomationPlugin.automationEvents.add(event)
else
AutomationPlugin.automationEvents[position] = event
dismiss()
RxBus.send(EventAutomationDataChanged())
}
// Cancel button
cancel.setOnClickListener { dismiss() }
showPreconditions() showPreconditions()
disposable.add(RxBus disposable.add(RxBus
@ -137,9 +103,33 @@ class EditEventDialog : DialogFragment() {
) )
} }
override fun onStart() { override fun submit() : Boolean{
super.onStart() // check for title
dialog?.window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT) val title = automation_inputEventTitle.text.toString()
if (title.isEmpty()) {
ToastUtils.showToastInUiThread(context, R.string.automation_missing_task_name)
return false
}
event.title = title
// check for at least one trigger
val con = event.trigger as TriggerConnector
if (con.size() == 0) {
ToastUtils.showToastInUiThread(context, R.string.automation_missing_trigger)
return false
}
// check for at least one action
if (event.actions.isEmpty()) {
ToastUtils.showToastInUiThread(context, R.string.automation_missing_action)
return false
}
// store
if (position == -1)
AutomationPlugin.automationEvents.add(event)
else
AutomationPlugin.automationEvents[position] = event
RxBus.send(EventAutomationDataChanged())
return true
} }
override fun onDestroyView() { override fun onDestroyView() {
@ -147,10 +137,10 @@ class EditEventDialog : DialogFragment() {
disposable.clear() disposable.clear()
} }
override fun onSaveInstanceState(bundle: Bundle) { override fun onSaveInstanceState(savedInstanceState: Bundle) {
super.onSaveInstanceState(bundle) super.onSaveInstanceState(savedInstanceState)
bundle.putString("event", event.toJSON()) savedInstanceState.putString("event", event.toJSON())
bundle.putInt("position", position) savedInstanceState.putInt("position", position)
} }
private fun showPreconditions() { private fun showPreconditions() {
@ -164,5 +154,4 @@ class EditEventDialog : DialogFragment() {
automation_forcedTriggerDescriptionLabel.visibility = View.GONE automation_forcedTriggerDescriptionLabel.visibility = View.GONE
} }
} }
} }

View file

@ -4,15 +4,14 @@ import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.fragment.app.DialogFragment
import info.nightscout.androidaps.R import info.nightscout.androidaps.R
import info.nightscout.androidaps.dialogs.DialogFragmentWithDate
import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationUpdateTrigger import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationUpdateTrigger
import info.nightscout.androidaps.plugins.general.automation.triggers.Trigger import info.nightscout.androidaps.plugins.general.automation.triggers.Trigger
import kotlinx.android.synthetic.main.automation_dialog_edit_trigger.* import kotlinx.android.synthetic.main.automation_dialog_edit_trigger.*
import kotlinx.android.synthetic.main.okcancel.*
class EditTriggerDialog : DialogFragment() { class EditTriggerDialog : DialogFragmentWithDate() {
private var trigger: Trigger? = null private var trigger: Trigger? = null
@ -23,7 +22,7 @@ class EditTriggerDialog : DialogFragment() {
bundle.getString("trigger")?.let { trigger = Trigger.instantiate(it) } bundle.getString("trigger")?.let { trigger = Trigger.instantiate(it) }
} }
dialog?.setCanceledOnTouchOutside(false) onCreateViewGeneral()
return inflater.inflate(R.layout.automation_dialog_edit_trigger, container, false) return inflater.inflate(R.layout.automation_dialog_edit_trigger, container, false)
} }
@ -32,24 +31,15 @@ class EditTriggerDialog : DialogFragment() {
// display root trigger // display root trigger
trigger?.generateDialog(automation_layoutTrigger, fragmentManager) trigger?.generateDialog(automation_layoutTrigger, fragmentManager)
}
// OK button override fun submit():Boolean {
ok.setOnClickListener {
dismiss()
trigger?.let { trigger -> RxBus.send(EventAutomationUpdateTrigger(trigger)) } trigger?.let { trigger -> RxBus.send(EventAutomationUpdateTrigger(trigger)) }
return true
} }
// Cancel button override fun onSaveInstanceState(savedInstanceState: Bundle) {
cancel.setOnClickListener { dismiss() } super.onSaveInstanceState(savedInstanceState)
} trigger?.let { savedInstanceState.putString("trigger", it.toJSON()) }
override fun onStart() {
super.onStart()
dialog?.window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
}
override fun onSaveInstanceState(bundle: Bundle) {
super.onSaveInstanceState(bundle)
trigger?.let { bundle.putString("trigger", it.toJSON()) }
} }
} }

View file

@ -75,7 +75,7 @@ public class TriggerListAdapter {
private Spinner createSpinner() { private Spinner createSpinner() {
Spinner spinner = new Spinner(mContext); Spinner spinner = new Spinner(mContext);
ArrayAdapter<String> spinnerArrayAdapter = new ArrayAdapter<>(mContext, android.R.layout.simple_spinner_item, TriggerConnector.Type.labels()); ArrayAdapter<String> spinnerArrayAdapter = new ArrayAdapter<>(mContext, R.layout.spinner_centered, TriggerConnector.Type.labels());
spinnerArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); spinnerArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(spinnerArrayAdapter); spinner.setAdapter(spinnerArrayAdapter);
return spinner; return spinner;

View file

@ -87,7 +87,7 @@ public class Comparator extends Element {
@Override @Override
public void addToLayout(LinearLayout root) { public void addToLayout(LinearLayout root) {
Spinner spinner = new Spinner(root.getContext()); Spinner spinner = new Spinner(root.getContext());
ArrayAdapter<String> spinnerArrayAdapter = new ArrayAdapter<>(root.getContext(), android.R.layout.simple_spinner_item, Compare.labels()); ArrayAdapter<String> spinnerArrayAdapter = new ArrayAdapter<>(root.getContext(), R.layout.spinner_centered, Compare.labels());
spinnerArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); spinnerArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(spinnerArrayAdapter); spinner.setAdapter(spinnerArrayAdapter);
LinearLayout.LayoutParams spinnerParams = new LinearLayout.LayoutParams( LinearLayout.LayoutParams spinnerParams = new LinearLayout.LayoutParams(

View file

@ -54,7 +54,7 @@ public class ComparatorExists extends Element {
@Override @Override
public void addToLayout(LinearLayout root) { public void addToLayout(LinearLayout root) {
Spinner spinner = new Spinner(root.getContext()); Spinner spinner = new Spinner(root.getContext());
ArrayAdapter<String> spinnerArrayAdapter = new ArrayAdapter<>(root.getContext(), android.R.layout.simple_spinner_item, Compare.labels()); ArrayAdapter<String> spinnerArrayAdapter = new ArrayAdapter<>(root.getContext(), R.layout.spinner_centered, Compare.labels());
spinnerArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); spinnerArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(spinnerArrayAdapter); spinner.setAdapter(spinnerArrayAdapter);
LinearLayout.LayoutParams spinnerParams = new LinearLayout.LayoutParams( LinearLayout.LayoutParams spinnerParams = new LinearLayout.LayoutParams(

View file

@ -87,7 +87,7 @@ public class InputDelta extends Element {
@Override @Override
public void addToLayout(LinearLayout root) { public void addToLayout(LinearLayout root) {
Spinner spinner = new Spinner(root.getContext()); Spinner spinner = new Spinner(root.getContext());
ArrayAdapter<String> spinnerArrayAdapter = new ArrayAdapter<>(root.getContext(), android.R.layout.simple_spinner_item, DeltaType.labels()); ArrayAdapter<String> spinnerArrayAdapter = new ArrayAdapter<>(root.getContext(), R.layout.spinner_centered, DeltaType.labels());
spinnerArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); spinnerArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(spinnerArrayAdapter); spinner.setAdapter(spinnerArrayAdapter);
LinearLayout.LayoutParams spinnerParams = new LinearLayout.LayoutParams( LinearLayout.LayoutParams spinnerParams = new LinearLayout.LayoutParams(

View file

@ -0,0 +1,107 @@
package info.nightscout.androidaps.plugins.general.automation.elements;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.LinearLayout;
import android.widget.Spinner;
import androidx.annotation.StringRes;
import java.util.ArrayList;
import java.util.List;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
public class InputLocationMode extends Element {
public enum Mode {
INSIDE,
OUTSIDE,
GOING_IN,
GOING_OUT;
public @StringRes
int getStringRes() {
switch (this) {
case INSIDE:
return R.string.location_inside;
case OUTSIDE:
return R.string.location_outside;
case GOING_IN:
return R.string.location_going_in;
case GOING_OUT:
return R.string.location_going_out;
default:
return R.string.unknown;
}
}
public static List<String> labels() {
List<String> list = new ArrayList<>();
for (Mode c : Mode.values()) {
list.add(MainApp.gs(c.getStringRes()));
}
return list;
}
public Mode fromString(String wanted){
for (Mode c : Mode.values()) {
if(c.toString() == wanted)
return c;
}
return null;
}
}
private Mode mode;
public InputLocationMode() {
super();
mode = Mode.INSIDE;
}
public InputLocationMode(InputLocationMode another) {
super();
this.mode = another.mode;
}
@Override
public void addToLayout(LinearLayout root) {
ArrayAdapter<String> adapter = new ArrayAdapter<>(root.getContext(),
R.layout.spinner_centered, Mode.labels());
Spinner spinner = new Spinner(root.getContext());
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
LinearLayout.LayoutParams spinnerParams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT
);
spinnerParams.setMargins(0, MainApp.dpToPx(4), 0, MainApp.dpToPx(4));
spinner.setLayoutParams(spinnerParams);
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
setValue(Mode.values()[position]);
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
spinner.setSelection(this.getValue().ordinal());
root.addView(spinner);
}
public Mode getValue() {
return mode;
}
public InputLocationMode setValue(Mode mode) {
this.mode = mode;
return this;
}
}

View file

@ -19,6 +19,7 @@ import info.nightscout.androidaps.R;
import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.plugins.general.automation.elements.InputButton; import info.nightscout.androidaps.plugins.general.automation.elements.InputButton;
import info.nightscout.androidaps.plugins.general.automation.elements.InputDouble; import info.nightscout.androidaps.plugins.general.automation.elements.InputDouble;
import info.nightscout.androidaps.plugins.general.automation.elements.InputLocationMode;
import info.nightscout.androidaps.plugins.general.automation.elements.InputString; import info.nightscout.androidaps.plugins.general.automation.elements.InputString;
import info.nightscout.androidaps.plugins.general.automation.elements.LabelWithElement; import info.nightscout.androidaps.plugins.general.automation.elements.LabelWithElement;
import info.nightscout.androidaps.plugins.general.automation.elements.LayoutBuilder; import info.nightscout.androidaps.plugins.general.automation.elements.LayoutBuilder;
@ -28,12 +29,17 @@ import info.nightscout.androidaps.utils.DateUtil;
import info.nightscout.androidaps.utils.JsonHelper; import info.nightscout.androidaps.utils.JsonHelper;
import info.nightscout.androidaps.utils.T; import info.nightscout.androidaps.utils.T;
import static info.nightscout.androidaps.plugins.general.automation.elements.InputLocationMode.Mode.*;
public class TriggerLocation extends Trigger { public class TriggerLocation extends Trigger {
private static Logger log = LoggerFactory.getLogger(L.AUTOMATION); private static Logger log = LoggerFactory.getLogger(L.AUTOMATION);
InputDouble latitude = new InputDouble(0d, -90d, +90d, 0.000001d, new DecimalFormat("0.000000")); InputDouble latitude = new InputDouble(0d, -90d, +90d, 0.000001d, new DecimalFormat("0.000000"));
InputDouble longitude = new InputDouble(0d, -180d, +180d, 0.000001d, new DecimalFormat("0.000000")); InputDouble longitude = new InputDouble(0d, -180d, +180d, 0.000001d, new DecimalFormat("0.000000"));
InputDouble distance = new InputDouble(200d, 0, 100000, 10d, new DecimalFormat("0")); InputDouble distance = new InputDouble(200d, 0, 100000, 10d, new DecimalFormat("0"));
InputLocationMode modeSelected = new InputLocationMode();
InputLocationMode.Mode lastMode = INSIDE;
InputString name = new InputString(); InputString name = new InputString();
private Runnable buttonAction = () -> { private Runnable buttonAction = () -> {
@ -54,13 +60,16 @@ public class TriggerLocation extends Trigger {
latitude = new InputDouble(triggerLocation.latitude); latitude = new InputDouble(triggerLocation.latitude);
longitude = new InputDouble(triggerLocation.longitude); longitude = new InputDouble(triggerLocation.longitude);
distance = new InputDouble(triggerLocation.distance); distance = new InputDouble(triggerLocation.distance);
modeSelected = new InputLocationMode(triggerLocation.modeSelected);
if (modeSelected.getValue() == GOING_OUT)
lastMode = OUTSIDE;
lastRun = triggerLocation.lastRun; lastRun = triggerLocation.lastRun;
name = triggerLocation.name; name = triggerLocation.name;
} }
@Override @Override
public synchronized boolean shouldRun() { public synchronized boolean shouldRun() {
Location location = LocationService.getLastLocation(); Location location = this.getCurrentLocation();
if (location == null) if (location == null)
return false; return false;
@ -72,11 +81,20 @@ public class TriggerLocation extends Trigger {
a.setLongitude(longitude.getValue()); a.setLongitude(longitude.getValue());
double calculatedDistance = location.distanceTo(a); double calculatedDistance = location.distanceTo(a);
if (calculatedDistance < distance.getValue()) { // log.debug("Moded(current/last/wanted): "+(currentMode(calculatedDistance))+"/"+lastMode+"/"+modeSelected.getValue());
// log.debug("Distance: "+calculatedDistance + "("+distance.getValue()+")");
if ((modeSelected.getValue() == INSIDE) && (calculatedDistance <= distance.getValue()) ||
((modeSelected.getValue() == OUTSIDE) && (calculatedDistance > distance.getValue())) ||
((modeSelected.getValue() == GOING_IN) && (calculatedDistance <= distance.getValue()) && (lastMode == OUTSIDE)) ||
((modeSelected.getValue() == GOING_OUT) && (calculatedDistance > distance.getValue()) && (lastMode == INSIDE))
) {
if (L.isEnabled(L.AUTOMATION)) if (L.isEnabled(L.AUTOMATION))
log.debug("Ready for execution: " + friendlyDescription()); log.debug("Ready for execution: " + friendlyDescription());
lastMode = currentMode(calculatedDistance);
return true; return true;
} }
lastMode = currentMode(calculatedDistance); // current mode will be last mode for the next check
return false; return false;
} }
@ -90,6 +108,7 @@ public class TriggerLocation extends Trigger {
data.put("longitude", longitude.getValue()); data.put("longitude", longitude.getValue());
data.put("distance", distance.getValue()); data.put("distance", distance.getValue());
data.put("name", name.getValue()); data.put("name", name.getValue());
data.put("mode", modeSelected.getValue());
data.put("lastRun", lastRun); data.put("lastRun", lastRun);
o.put("data", data); o.put("data", data);
} catch (JSONException e) { } catch (JSONException e) {
@ -106,7 +125,10 @@ public class TriggerLocation extends Trigger {
longitude.setValue(JsonHelper.safeGetDouble(d, "longitude")); longitude.setValue(JsonHelper.safeGetDouble(d, "longitude"));
distance.setValue(JsonHelper.safeGetDouble(d, "distance")); distance.setValue(JsonHelper.safeGetDouble(d, "distance"));
name.setValue(JsonHelper.safeGetString(d, "name")); name.setValue(JsonHelper.safeGetString(d, "name"));
lastRun = JsonHelper.safeGetLong(d, "lastRun"); modeSelected.setValue(InputLocationMode.Mode.valueOf(JsonHelper.safeGetString(d, "mode")));
if (modeSelected.getValue() == GOING_OUT)
lastMode = OUTSIDE;
lastRun = DateUtil.now(); // set lastRun to now to give the service 5 mins to get the location properly
} catch (Exception e) { } catch (Exception e) {
log.error("Unhandled exception", e); log.error("Unhandled exception", e);
} }
@ -120,7 +142,7 @@ public class TriggerLocation extends Trigger {
@Override @Override
public String friendlyDescription() { public String friendlyDescription() {
return MainApp.gs(R.string.locationis, name.getValue()); return MainApp.gs(R.string.locationis, MainApp.gs(modeSelected.getValue().getStringRes()), " " + name.getValue());
} }
@Override @Override
@ -154,6 +176,11 @@ public class TriggerLocation extends Trigger {
return this; return this;
} }
TriggerLocation setMode(InputLocationMode.Mode value) {
modeSelected.setValue(value);
return this;
}
@Override @Override
public void generateDialog(LinearLayout root, FragmentManager fragmentManager) { public void generateDialog(LinearLayout root, FragmentManager fragmentManager) {
new LayoutBuilder() new LayoutBuilder()
@ -162,7 +189,21 @@ public class TriggerLocation extends Trigger {
.add(new LabelWithElement(MainApp.gs(R.string.latitude_short), "", latitude)) .add(new LabelWithElement(MainApp.gs(R.string.latitude_short), "", latitude))
.add(new LabelWithElement(MainApp.gs(R.string.longitude_short), "", longitude)) .add(new LabelWithElement(MainApp.gs(R.string.longitude_short), "", longitude))
.add(new LabelWithElement(MainApp.gs(R.string.distance_short), "", distance)) .add(new LabelWithElement(MainApp.gs(R.string.distance_short), "", distance))
.add(new LabelWithElement(MainApp.gs(R.string.location_mode), "", modeSelected))
.add(new InputButton(MainApp.gs(R.string.currentlocation), buttonAction), LocationService.getLastLocation() != null) .add(new InputButton(MainApp.gs(R.string.currentlocation), buttonAction), LocationService.getLastLocation() != null)
.build(root); .build(root);
} }
// Method to return the actual mode based on the current distance
InputLocationMode.Mode currentMode(double currentDistance){
if ( currentDistance <= this.distance.getValue() )
return INSIDE;
else
return OUTSIDE;
}
static Location getCurrentLocation(){
return LocationService.getLastLocation();
}
} }

View file

@ -93,7 +93,7 @@ public class TriggerTempTarget extends Trigger {
@Override @Override
public int friendlyName() { public int friendlyName() {
return R.string.temptarget; return R.string.careportal_temporarytarget;
} }
@Override @Override
@ -124,7 +124,7 @@ public class TriggerTempTarget extends Trigger {
@Override @Override
public void generateDialog(LinearLayout root, FragmentManager fragmentManager) { public void generateDialog(LinearLayout root, FragmentManager fragmentManager) {
new LayoutBuilder() new LayoutBuilder()
.add(new StaticLabel(R.string.temptarget)) .add(new StaticLabel(R.string.careportal_temporarytarget))
.add(comparator) .add(comparator)
.build(root); .build(root);
} }

View file

@ -63,7 +63,6 @@ public class CareportalFragment extends Fragment implements View.OnClickListener
public static final OptionsToShow TEMPBASALSTART = new OptionsToShow(R.id.careportal_tempbasalstart, R.string.careportal_tempbasalstart).date().bg().duration().percent().absolute(); public static final OptionsToShow TEMPBASALSTART = new OptionsToShow(R.id.careportal_tempbasalstart, R.string.careportal_tempbasalstart).date().bg().duration().percent().absolute();
public static final OptionsToShow TEMPBASALEND = new OptionsToShow(R.id.careportal_tempbasalend, R.string.careportal_tempbasalend).date().bg(); public static final OptionsToShow TEMPBASALEND = new OptionsToShow(R.id.careportal_tempbasalend, R.string.careportal_tempbasalend).date().bg();
public static final OptionsToShow PROFILESWITCH = new OptionsToShow(R.id.careportal_profileswitch, R.string.careportal_profileswitch).date().duration().profile(); public static final OptionsToShow PROFILESWITCH = new OptionsToShow(R.id.careportal_profileswitch, R.string.careportal_profileswitch).date().duration().profile();
public static final OptionsToShow PROFILESWITCHDIRECT = new OptionsToShow(R.id.careportal_profileswitch, R.string.careportal_profileswitch).duration().profile();
public static final OptionsToShow OPENAPSOFFLINE = new OptionsToShow(R.id.careportal_openapsoffline, R.string.careportal_openapsoffline).date().duration(); public static final OptionsToShow OPENAPSOFFLINE = new OptionsToShow(R.id.careportal_openapsoffline, R.string.careportal_openapsoffline).date().duration();
public static final OptionsToShow TEMPTARGET = new OptionsToShow(R.id.careportal_temporarytarget, R.string.careportal_temporarytarget).date().duration().tempTarget(); public static final OptionsToShow TEMPTARGET = new OptionsToShow(R.id.careportal_temporarytarget, R.string.careportal_temporarytarget).date().duration().tempTarget();
@ -180,7 +179,6 @@ public class CareportalFragment extends Fragment implements View.OnClickListener
newDialog.setOptions(NOTE, R.string.careportal_note); newDialog.setOptions(NOTE, R.string.careportal_note);
break; break;
case R.id.careportal_profileswitch: case R.id.careportal_profileswitch:
PROFILESWITCH.executeProfileSwitch = false;
newDialog.setOptions(PROFILESWITCH, R.string.careportal_profileswitch); newDialog.setOptions(PROFILESWITCH, R.string.careportal_profileswitch);
break; break;
case R.id.careportal_pumpsitechange: case R.id.careportal_pumpsitechange:
@ -202,7 +200,6 @@ public class CareportalFragment extends Fragment implements View.OnClickListener
newDialog.setOptions(OPENAPSOFFLINE, R.string.careportal_openapsoffline); newDialog.setOptions(OPENAPSOFFLINE, R.string.careportal_openapsoffline);
break; break;
case R.id.careportal_temporarytarget: case R.id.careportal_temporarytarget:
TEMPTARGET.executeTempTarget = false;
newDialog.setOptions(TEMPTARGET, R.string.careportal_temporarytarget); newDialog.setOptions(TEMPTARGET, R.string.careportal_temporarytarget);
break; break;
default: default:
@ -222,7 +219,7 @@ public class CareportalFragment extends Fragment implements View.OnClickListener
activity.runOnUiThread( activity.runOnUiThread(
() -> { () -> {
CareportalEvent careportalEvent; CareportalEvent careportalEvent;
NSSettingsStatus nsSettings = new NSSettingsStatus().getInstance(); NSSettingsStatus nsSettings = NSSettingsStatus.getInstance();
double iageUrgent = nsSettings.getExtendedWarnValue("iage", "urgent", 96); double iageUrgent = nsSettings.getExtendedWarnValue("iage", "urgent", 96);
double iageWarn = nsSettings.getExtendedWarnValue("iage", "warn", 72); double iageWarn = nsSettings.getExtendedWarnValue("iage", "warn", 72);

View file

@ -1,5 +1,6 @@
package info.nightscout.androidaps.plugins.general.careportal; package info.nightscout.androidaps.plugins.general.careportal;
import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.R; import info.nightscout.androidaps.R;
import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.PluginBase;
import info.nightscout.androidaps.interfaces.PluginDescription; import info.nightscout.androidaps.interfaces.PluginDescription;
@ -22,10 +23,14 @@ public class CareportalPlugin extends PluginBase {
.fragmentClass(CareportalFragment.class.getName()) .fragmentClass(CareportalFragment.class.getName())
.pluginName(R.string.careportal) .pluginName(R.string.careportal)
.shortName(R.string.careportal_shortname) .shortName(R.string.careportal_shortname)
.visibleByDefault(true) .visibleByDefault(Config.NSCLIENT)
.enableByDefault(true) .enableByDefault(Config.NSCLIENT)
.description(R.string.description_careportal) .description(R.string.description_careportal)
); );
} }
@Override
public boolean specialEnableCondition() {
return Config.NSCLIENT;
}
} }

View file

@ -1,7 +1,6 @@
package info.nightscout.androidaps.plugins.general.careportal.Dialogs; package info.nightscout.androidaps.plugins.general.careportal.Dialogs;
import android.content.Context;
import android.os.Bundle; import android.os.Bundle;
import android.text.Editable; import android.text.Editable;
import android.text.TextWatcher; import android.text.TextWatcher;
@ -9,6 +8,8 @@ import android.text.format.DateFormat;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.AdapterView; import android.widget.AdapterView;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.Button; import android.widget.Button;
@ -18,7 +19,6 @@ import android.widget.RadioButton;
import android.widget.Spinner; import android.widget.Spinner;
import android.widget.TextView; import android.widget.TextView;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatDialogFragment; import androidx.appcompat.app.AppCompatDialogFragment;
import androidx.fragment.app.DialogFragment; import androidx.fragment.app.DialogFragment;
@ -45,8 +45,6 @@ import info.nightscout.androidaps.data.ProfileStore;
import info.nightscout.androidaps.db.BgReading; import info.nightscout.androidaps.db.BgReading;
import info.nightscout.androidaps.db.CareportalEvent; import info.nightscout.androidaps.db.CareportalEvent;
import info.nightscout.androidaps.db.ProfileSwitch; import info.nightscout.androidaps.db.ProfileSwitch;
import info.nightscout.androidaps.db.Source;
import info.nightscout.androidaps.db.TempTarget;
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
import info.nightscout.androidaps.plugins.general.careportal.OptionsToShow; import info.nightscout.androidaps.plugins.general.careportal.OptionsToShow;
@ -58,6 +56,7 @@ import info.nightscout.androidaps.utils.DefaultValueHelper;
import info.nightscout.androidaps.utils.HardLimits; import info.nightscout.androidaps.utils.HardLimits;
import info.nightscout.androidaps.utils.JsonHelper; import info.nightscout.androidaps.utils.JsonHelper;
import info.nightscout.androidaps.utils.NumberPicker; import info.nightscout.androidaps.utils.NumberPicker;
import info.nightscout.androidaps.utils.OKDialog;
import info.nightscout.androidaps.utils.SP; import info.nightscout.androidaps.utils.SP;
import info.nightscout.androidaps.utils.SafeParse; import info.nightscout.androidaps.utils.SafeParse;
import info.nightscout.androidaps.utils.Translator; import info.nightscout.androidaps.utils.Translator;
@ -68,7 +67,7 @@ public class NewNSTreatmentDialog extends AppCompatDialogFragment implements Vie
private static OptionsToShow options; private static OptionsToShow options;
private static String event; private static String event;
Profile profile; private Profile profile;
public ProfileStore profileStore; public ProfileStore profileStore;
TextView eventTypeText; TextView eventTypeText;
@ -105,9 +104,10 @@ public class NewNSTreatmentDialog extends AppCompatDialogFragment implements Vie
private static Integer seconds = null; private static Integer seconds = null;
public void setOptions(OptionsToShow options, int event) { public NewNSTreatmentDialog setOptions(OptionsToShow options, int event) {
this.options = options; this.options = options;
this.event = MainApp.gs(event); this.event = MainApp.gs(event);
return this;
} }
public NewNSTreatmentDialog() { public NewNSTreatmentDialog() {
@ -122,7 +122,10 @@ public class NewNSTreatmentDialog extends AppCompatDialogFragment implements Vie
public View onCreateView(LayoutInflater inflater, ViewGroup container, public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) { Bundle savedInstanceState) {
if (options == null) return null; if (options == null) return null;
getDialog().setTitle(MainApp.gs(options.eventName)); getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
setCancelable(true);
getDialog().setCanceledOnTouchOutside(false);
setStyle(DialogFragment.STYLE_NORMAL, getTheme()); setStyle(DialogFragment.STYLE_NORMAL, getTheme());
View view = inflater.inflate(R.layout.careportal_newnstreatment_dialog, container, false); View view = inflater.inflate(R.layout.careportal_newnstreatment_dialog, container, false);
@ -200,16 +203,15 @@ public class NewNSTreatmentDialog extends AppCompatDialogFragment implements Vie
boolean erase = false; boolean erase = false;
String units = ProfileFunctions.getSystemUnits(); String units = ProfileFunctions.getSystemUnits();
DefaultValueHelper helper = new DefaultValueHelper();
if (MainApp.gs(R.string.eatingsoon).equals(reasonList.get(position))) { if (MainApp.gs(R.string.eatingsoon).equals(reasonList.get(position))) {
defaultDuration = helper.determineEatingSoonTTDuration(); defaultDuration = DefaultValueHelper.determineEatingSoonTTDuration();
defaultTarget = helper.determineEatingSoonTT(); defaultTarget = DefaultValueHelper.determineEatingSoonTT();
} else if (MainApp.gs(R.string.activity).equals(reasonList.get(position))) { } else if (MainApp.gs(R.string.activity).equals(reasonList.get(position))) {
defaultDuration = helper.determineActivityTTDuration(); defaultDuration = DefaultValueHelper.determineActivityTTDuration();
defaultTarget = helper.determineActivityTT(); defaultTarget = DefaultValueHelper.determineActivityTT();
} else if (MainApp.gs(R.string.hypo).equals(reasonList.get(position))) { } else if (MainApp.gs(R.string.hypo).equals(reasonList.get(position))) {
defaultDuration = helper.determineHypoTTDuration(); defaultDuration = DefaultValueHelper.determineHypoTTDuration();
defaultTarget = helper.determineHypoTT(); defaultTarget = DefaultValueHelper.determineHypoTT();
} else if (editDuration.getValue() != 0) { } else if (editDuration.getValue() != 0) {
defaultDuration = editDuration.getValue(); defaultDuration = editDuration.getValue();
} else { } else {
@ -394,6 +396,13 @@ public class NewNSTreatmentDialog extends AppCompatDialogFragment implements Vie
return view; return view;
} }
@Override
public void onResume() {
super.onResume();
getDialog().getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
}
@Override @Override
public void onClick(View view) { public void onClick(View view) {
Calendar calendar = Calendar.getInstance(); Calendar calendar = Calendar.getInstance();
@ -585,12 +594,12 @@ public class NewNSTreatmentDialog extends AppCompatDialogFragment implements Vie
String buildConfirmText(JSONObject data) { String buildConfirmText(JSONObject data) {
String ret = ""; String ret = "";
if (data.has("eventType")) { // if (data.has("eventType")) {
ret += MainApp.gs(R.string.careportal_newnstreatment_eventtype); // ret += MainApp.gs(R.string.careportal_newnstreatment_eventtype);
ret += ": "; // ret += ": ";
ret += Translator.translate(JsonHelper.safeGetString(data, "eventType", "")); // ret += Translator.translate(JsonHelper.safeGetString(data, "eventType", ""));
ret += "\n"; // ret += "\n";
} // }
if (data.has("glucose")) { if (data.has("glucose")) {
ret += MainApp.gs(R.string.treatments_wizard_bg_label); ret += MainApp.gs(R.string.treatments_wizard_bg_label);
ret += ": "; ret += ": ";
@ -672,7 +681,7 @@ public class NewNSTreatmentDialog extends AppCompatDialogFragment implements Vie
ret += "\n"; ret += "\n";
} }
if (data.has("created_at")) { if (data.has("created_at")) {
ret += MainApp.gs(R.string.careportal_newnstreatment_eventtime_label); ret += MainApp.gs(R.string.event_time_label);
ret += ": "; ret += ": ";
ret += eventTime.toLocaleString(); ret += eventTime.toLocaleString();
ret += "\n"; ret += "\n";
@ -687,50 +696,15 @@ public class NewNSTreatmentDialog extends AppCompatDialogFragment implements Vie
return ret; return ret;
} }
void confirmNSTreatmentCreation() { private void confirmNSTreatmentCreation() {
Context context = getContext();
if (context != null) {
final JSONObject data = gatherData(); final JSONObject data = gatherData();
final String confirmText = buildConfirmText(data); OKDialog.showConfirmation(getContext(), Translator.translate(JsonHelper.safeGetString(data, "eventType", MainApp.gs(R.string.overview_treatment_label))), buildConfirmText(data), () -> createNSTreatment(data));
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(MainApp.gs(R.string.confirmation));
builder.setMessage(confirmText);
builder.setPositiveButton(MainApp.gs(R.string.ok), (dialog, id) -> createNSTreatment(data));
builder.setNegativeButton(MainApp.gs(R.string.cancel), null);
builder.show();
}
} }
void createNSTreatment(JSONObject data) { void createNSTreatment(JSONObject data) {
if (options.executeProfileSwitch) { if (JsonHelper.safeGetString(data, "eventType", "").equals(CareportalEvent.PROFILESWITCH)) {
if (data.has("profile")) { ProfileSwitch profileSwitch = ProfileFunctions.getInstance().prepareProfileSwitch(
ProfileFunctions.doProfileSwitch(profileStore, JsonHelper.safeGetString(data, "profile"), JsonHelper.safeGetInt(data, "duration"), JsonHelper.safeGetInt(data, "percentage"), JsonHelper.safeGetInt(data, "timeshift"));
}
} else if (options.executeTempTarget) {
final int duration = JsonHelper.safeGetInt(data, "duration");
final double targetBottom = JsonHelper.safeGetDouble(data, "targetBottom");
final double targetTop = JsonHelper.safeGetDouble(data, "targetTop");
final String reason = JsonHelper.safeGetString(data, "reason", "");
if ((targetBottom != 0d && targetTop != 0d) || duration == 0) {
TempTarget tempTarget = new TempTarget()
.date(eventTime.getTime())
.duration(duration)
.reason(reason)
.source(Source.USER);
if (tempTarget.durationInMinutes != 0) {
tempTarget.low(Profile.toMgdl(targetBottom, ProfileFunctions.getSystemUnits()))
.high(Profile.toMgdl(targetTop, ProfileFunctions.getSystemUnits()));
} else {
tempTarget.low(0).high(0);
}
TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget);
}
if (duration == 10)
SP.putBoolean(R.string.key_objectiveusetemptarget, true);
} else {
if (JsonHelper.safeGetString(data, "eventType").equals(CareportalEvent.PROFILESWITCH)) {
ProfileSwitch profileSwitch = ProfileFunctions.prepareProfileSwitch(
profileStore, profileStore,
JsonHelper.safeGetString(data, "profile"), JsonHelper.safeGetString(data, "profile"),
JsonHelper.safeGetInt(data, "duration"), JsonHelper.safeGetInt(data, "duration"),
@ -743,7 +717,6 @@ public class NewNSTreatmentDialog extends AppCompatDialogFragment implements Vie
NSUpload.uploadCareportalEntryToNS(data); NSUpload.uploadCareportalEntryToNS(data);
} }
} }
}
@Override @Override
public void onSaveInstanceState(Bundle savedInstanceState) { public void onSaveInstanceState(Bundle savedInstanceState) {

View file

@ -19,10 +19,6 @@ public class OptionsToShow {
public boolean split; public boolean split;
public boolean tempTarget; public boolean tempTarget;
// perform direct actions
public boolean executeProfileSwitch = false;
public boolean executeTempTarget = false;
public OptionsToShow(int eventType, int eventName) { public OptionsToShow(int eventType, int eventName) {
this.eventType = eventType; this.eventType = eventType;
this.eventName = eventName; this.eventName = eventName;

View file

@ -1,6 +1,5 @@
package info.nightscout.androidaps.plugins.general.food; package info.nightscout.androidaps.plugins.general.food;
import android.content.DialogInterface;
import android.graphics.Paint; import android.graphics.Paint;
import android.os.Bundle; import android.os.Bundle;
import android.text.Editable; import android.text.Editable;
@ -14,14 +13,11 @@ import android.widget.EditText;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import androidx.appcompat.app.AlertDialog; import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
@ -33,6 +29,7 @@ import info.nightscout.androidaps.events.EventFoodDatabaseChanged;
import info.nightscout.androidaps.plugins.bus.RxBus; import info.nightscout.androidaps.plugins.bus.RxBus;
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload; import info.nightscout.androidaps.plugins.general.nsclient.NSUpload;
import info.nightscout.androidaps.utils.FabricPrivacy; import info.nightscout.androidaps.utils.FabricPrivacy;
import info.nightscout.androidaps.utils.OKDialog;
import info.nightscout.androidaps.utils.SpinnerHelper; import info.nightscout.androidaps.utils.SpinnerHelper;
import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable; import io.reactivex.disposables.CompositeDisposable;
@ -42,43 +39,36 @@ import io.reactivex.disposables.CompositeDisposable;
*/ */
public class FoodFragment extends Fragment { public class FoodFragment extends Fragment {
private static Logger log = LoggerFactory.getLogger(FoodFragment.class);
private CompositeDisposable disposable = new CompositeDisposable(); private CompositeDisposable disposable = new CompositeDisposable();
EditText filter; private EditText filter;
ImageView clearFilter; private SpinnerHelper category;
SpinnerHelper category; private SpinnerHelper subcategory;
SpinnerHelper subcategory; private RecyclerView recyclerView;
RecyclerView recyclerView;
List<Food> unfiltered; private List<Food> unfiltered;
List<Food> filtered; private List<Food> filtered;
ArrayList<CharSequence> categories;
ArrayList<CharSequence> subcategories;
final String EMPTY = MainApp.gs(R.string.none); private final String EMPTY = MainApp.gs(R.string.none);
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) { Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.food_fragment, container, false); View view = inflater.inflate(R.layout.food_fragment, container, false);
filter = (EditText) view.findViewById(R.id.food_filter); filter = view.findViewById(R.id.food_filter);
clearFilter = (ImageView) view.findViewById(R.id.food_clearfilter); ImageView clearFilter = view.findViewById(R.id.food_clearfilter);
category = new SpinnerHelper(view.findViewById(R.id.food_category)); category = new SpinnerHelper(view.findViewById(R.id.food_category));
subcategory = new SpinnerHelper(view.findViewById(R.id.food_subcategory)); subcategory = new SpinnerHelper(view.findViewById(R.id.food_subcategory));
recyclerView = (RecyclerView) view.findViewById(R.id.food_recyclerview); recyclerView = view.findViewById(R.id.food_recyclerview);
recyclerView.setHasFixedSize(true); recyclerView.setHasFixedSize(true);
LinearLayoutManager llm = new LinearLayoutManager(view.getContext()); LinearLayoutManager llm = new LinearLayoutManager(view.getContext());
recyclerView.setLayoutManager(llm); recyclerView.setLayoutManager(llm);
clearFilter.setOnClickListener(new View.OnClickListener() { clearFilter.setOnClickListener(v -> {
@Override
public void onClick(View v) {
filter.setText(""); filter.setText("");
category.setSelection(0); category.setSelection(0);
subcategory.setSelection(0); subcategory.setSelection(0);
filterData(); filterData();
}
}); });
category.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { category.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@ -149,11 +139,11 @@ public class FoodFragment extends Fragment {
disposable.clear(); disposable.clear();
} }
void loadData() { private void loadData() {
unfiltered = FoodPlugin.getPlugin().getService().getFoodData(); unfiltered = FoodPlugin.getPlugin().getService().getFoodData();
} }
void fillCategories() { private void fillCategories() {
Set<CharSequence> catSet = new HashSet<>(); Set<CharSequence> catSet = new HashSet<>();
for (Food f : unfiltered) { for (Food f : unfiltered) {
@ -162,7 +152,7 @@ public class FoodFragment extends Fragment {
} }
// make it unique // make it unique
categories = new ArrayList<>(catSet); ArrayList<CharSequence> categories = new ArrayList<>(catSet);
categories.add(0, MainApp.gs(R.string.none)); categories.add(0, MainApp.gs(R.string.none));
ArrayAdapter<CharSequence> adapterCategories = new ArrayAdapter<>(getContext(), ArrayAdapter<CharSequence> adapterCategories = new ArrayAdapter<>(getContext(),
@ -170,7 +160,7 @@ public class FoodFragment extends Fragment {
category.setAdapter(adapterCategories); category.setAdapter(adapterCategories);
} }
void fillSubcategories() { private void fillSubcategories() {
String categoryFilter = category.getSelectedItem().toString(); String categoryFilter = category.getSelectedItem().toString();
Set<CharSequence> subCatSet = new HashSet<>(); Set<CharSequence> subCatSet = new HashSet<>();
@ -184,7 +174,7 @@ public class FoodFragment extends Fragment {
} }
// make it unique // make it unique
subcategories = new ArrayList<>(subCatSet); ArrayList<CharSequence> subcategories = new ArrayList<>(subCatSet);
subcategories.add(0, MainApp.gs(R.string.none)); subcategories.add(0, MainApp.gs(R.string.none));
ArrayAdapter<CharSequence> adapterSubcategories = new ArrayAdapter<>(getContext(), ArrayAdapter<CharSequence> adapterSubcategories = new ArrayAdapter<>(getContext(),
@ -192,7 +182,7 @@ public class FoodFragment extends Fragment {
subcategory.setAdapter(adapterSubcategories); subcategory.setAdapter(adapterSubcategories);
} }
void filterData() { private void filterData() {
String textFilter = filter.getText().toString(); String textFilter = filter.getText().toString();
String categoryFilter = category.getSelectedItem().toString(); String categoryFilter = category.getSelectedItem().toString();
String subcategoryFilter = subcategory.getSelectedItem().toString(); String subcategoryFilter = subcategory.getSelectedItem().toString();
@ -227,6 +217,7 @@ public class FoodFragment extends Fragment {
this.foodList = foodList; this.foodList = foodList;
} }
@NonNull
@Override @Override
public FoodsViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) { public FoodsViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.food_item, viewGroup, false); View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.food_item, viewGroup, false);
@ -257,7 +248,7 @@ public class FoodFragment extends Fragment {
return foodList.size(); return foodList.size();
} }
class FoodsViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { class FoodsViewHolder extends RecyclerView.ViewHolder {
TextView name; TextView name;
TextView portion; TextView portion;
TextView carbs; TextView carbs;
@ -269,43 +260,26 @@ public class FoodFragment extends Fragment {
FoodsViewHolder(View itemView) { FoodsViewHolder(View itemView) {
super(itemView); super(itemView);
name = (TextView) itemView.findViewById(R.id.food_name); name = itemView.findViewById(R.id.food_name);
portion = (TextView) itemView.findViewById(R.id.food_portion); portion = itemView.findViewById(R.id.food_portion);
carbs = (TextView) itemView.findViewById(R.id.food_carbs); carbs = itemView.findViewById(R.id.food_carbs);
fat = (TextView) itemView.findViewById(R.id.food_fat); fat = itemView.findViewById(R.id.food_fat);
protein = (TextView) itemView.findViewById(R.id.food_protein); protein = itemView.findViewById(R.id.food_protein);
energy = (TextView) itemView.findViewById(R.id.food_energy); energy = itemView.findViewById(R.id.food_energy);
ns = (TextView) itemView.findViewById(R.id.ns_sign); ns = itemView.findViewById(R.id.ns_sign);
remove = (TextView) itemView.findViewById(R.id.food_remove); remove = itemView.findViewById(R.id.food_remove);
remove.setOnClickListener(this); remove.setOnClickListener(v -> {
remove.setPaintFlags(remove.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG);
}
@Override
public void onClick(View v) {
final Food food = (Food) v.getTag(); final Food food = (Food) v.getTag();
switch (v.getId()) { OKDialog.showConfirmation(getContext(), MainApp.gs(R.string.confirmation), MainApp.gs(R.string.removerecord) + "\n" + food.name, (dialog, id) -> {
case R.id.food_remove:
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setTitle(MainApp.gs(R.string.confirmation));
builder.setMessage(MainApp.gs(R.string.removerecord) + "\n" + food.name);
builder.setPositiveButton(MainApp.gs(R.string.ok), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
final String _id = food._id; final String _id = food._id;
if (_id != null && !_id.equals("")) { if (_id != null && !_id.equals("")) {
NSUpload.removeFoodFromNS(_id); NSUpload.removeFoodFromNS(_id);
} }
FoodPlugin.getPlugin().getService().delete(food); FoodPlugin.getPlugin().getService().delete(food);
} }, null);
}); });
builder.setNegativeButton(MainApp.gs(R.string.cancel), null); remove.setPaintFlags(remove.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG);
builder.show();
break;
} }
} }
} }
}
} }

View file

@ -2,15 +2,14 @@ package info.nightscout.androidaps.plugins.general.maintenance;
import android.Manifest; import android.Manifest;
import android.app.Activity; import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.os.Environment; import android.os.Environment;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import androidx.core.app.ActivityCompat;
import androidx.fragment.app.Fragment;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -39,7 +38,7 @@ import info.nightscout.androidaps.utils.ToastUtils;
public class ImportExportPrefs { public class ImportExportPrefs {
private static Logger log = LoggerFactory.getLogger(L.CORE); private static Logger log = LoggerFactory.getLogger(L.CORE);
static File path = new File(Environment.getExternalStorageDirectory().toString()); private static File path = new File(Environment.getExternalStorageDirectory().toString());
static public final File file = new File(path, MainApp.gs(R.string.app_name) + "Preferences"); static public final File file = new File(path, MainApp.gs(R.string.app_name) + "Preferences");
private static final int REQUEST_EXTERNAL_STORAGE = 1; private static final int REQUEST_EXTERNAL_STORAGE = 1;
@ -48,21 +47,7 @@ public class ImportExportPrefs {
Manifest.permission.WRITE_EXTERNAL_STORAGE Manifest.permission.WRITE_EXTERNAL_STORAGE
}; };
public static void verifyStoragePermissions(Activity activity) { static void verifyStoragePermissions(Fragment fragment) {
// Check if we have write permission
int permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (permission != PackageManager.PERMISSION_GRANTED) {
// We don't have permission so prompt the user
ActivityCompat.requestPermissions(
activity,
PERMISSIONS_STORAGE,
REQUEST_EXTERNAL_STORAGE
);
}
}
public static void verifyStoragePermissions(Fragment fragment) {
int permission = ContextCompat.checkSelfPermission(fragment.getContext(), int permission = ContextCompat.checkSelfPermission(fragment.getContext(),
Manifest.permission.WRITE_EXTERNAL_STORAGE); Manifest.permission.WRITE_EXTERNAL_STORAGE);
@ -73,17 +58,13 @@ public class ImportExportPrefs {
} }
public static void exportSharedPreferences(final Fragment f) { static void exportSharedPreferences(final Fragment f) {
exportSharedPreferences(f.getContext()); exportSharedPreferences(f.getContext());
} }
public static void exportSharedPreferences(final Context c) { private static void exportSharedPreferences(final Context context) {
OKDialog.showConfirmation(context, MainApp.gs(R.string.maintenance), MainApp.gs(R.string.export_to) + " " + file + " ?", () -> {
new AlertDialog.Builder(c) SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
.setMessage(MainApp.gs(R.string.export_to) + " " + file + " ?")
.setPositiveButton(android.R.string.yes, (dialog, which) -> {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(c);
try { try {
FileWriter fw = new FileWriter(file); FileWriter fw = new FileWriter(file);
PrintWriter pw = new PrintWriter(fw); PrintWriter pw = new PrintWriter(fw);
@ -93,27 +74,22 @@ public class ImportExportPrefs {
} }
pw.close(); pw.close();
fw.close(); fw.close();
ToastUtils.showToastInUiThread(c, MainApp.gs(R.string.exported)); ToastUtils.showToastInUiThread(context, MainApp.gs(R.string.exported));
} catch (FileNotFoundException e) { } catch (FileNotFoundException e) {
ToastUtils.showToastInUiThread(c, MainApp.gs(R.string.filenotfound) + " " + file); ToastUtils.showToastInUiThread(context, MainApp.gs(R.string.filenotfound) + " " + file);
log.error("Unhandled exception", e); log.error("Unhandled exception", e);
} catch (IOException e) { } catch (IOException e) {
log.error("Unhandled exception", e); log.error("Unhandled exception", e);
} }
}) });
.setNegativeButton(android.R.string.cancel, null)
.show();
} }
public static void importSharedPreferences(final Fragment fragment) { static void importSharedPreferences(final Fragment fragment) {
importSharedPreferences(fragment.getContext()); importSharedPreferences(fragment.getContext());
} }
public static void importSharedPreferences(final Context context) { public static void importSharedPreferences(final Context context) {
new AlertDialog.Builder(context) OKDialog.showConfirmation(context, MainApp.gs(R.string.maintenance), MainApp.gs(R.string.import_from) + " " + file + " ?", () -> {
.setMessage(MainApp.gs(R.string.import_from) + " " + file + " ?")
.setPositiveButton(android.R.string.yes, (dialog, which) -> {
String line; String line;
String[] lineParts; String[] lineParts;
try { try {
@ -134,11 +110,9 @@ public class ImportExportPrefs {
SP.putBoolean(R.string.key_setupwizard_processed, true); SP.putBoolean(R.string.key_setupwizard_processed, true);
OKDialog.show(context, MainApp.gs(R.string.setting_imported), MainApp.gs(R.string.restartingapp), () -> { OKDialog.show(context, MainApp.gs(R.string.setting_imported), MainApp.gs(R.string.restartingapp), () -> {
log.debug("Exiting"); log.debug("Exiting");
MainApp.instance().stopKeepAliveService();
RxBus.INSTANCE.send(new EventAppExit()); RxBus.INSTANCE.send(new EventAppExit());
MainApp.closeDbHelper();
if (context instanceof Activity) { if (context instanceof Activity) {
((Activity)context).finish(); ((Activity) context).finish();
} }
System.runFinalization(); System.runFinalization();
System.exit(0); System.exit(0);
@ -149,9 +123,6 @@ public class ImportExportPrefs {
} catch (IOException e) { } catch (IOException e) {
log.error("Unhandled exception", e); log.error("Unhandled exception", e);
} }
}) });
.setNegativeButton(android.R.string.cancel, null)
.show();
} }
} }

View file

@ -2,81 +2,58 @@ package info.nightscout.androidaps.plugins.general.maintenance;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import androidx.fragment.app.Fragment;
import androidx.appcompat.app.AlertDialog;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import androidx.fragment.app.Fragment;
import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R; import info.nightscout.androidaps.R;
import info.nightscout.androidaps.plugins.general.food.FoodPlugin; import info.nightscout.androidaps.plugins.general.food.FoodPlugin;
import info.nightscout.androidaps.plugins.general.maintenance.activities.LogSettingActivity; import info.nightscout.androidaps.plugins.general.maintenance.activities.LogSettingActivity;
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin; import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
import info.nightscout.androidaps.utils.OKDialog;
/** /**
* *
*/ */
public class MaintenanceFragment extends Fragment { public class MaintenanceFragment extends Fragment {
private Fragment f;
@Override
public void onResume() {
super.onResume();
this.f = this;
}
@Override
public void onPause() {
super.onPause();
this.f = null;
}
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) { Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.maintenance_fragment, container, false); View view = inflater.inflate(R.layout.maintenance_fragment, container, false);
final Fragment f = this;
view.findViewById(R.id.log_send).setOnClickListener(view1 -> MaintenancePlugin.getPlugin().sendLogs()); view.findViewById(R.id.log_send).setOnClickListener(view1 -> MaintenancePlugin.getPlugin().sendLogs());
view.findViewById(R.id.log_delete).setOnClickListener(view1 -> MaintenancePlugin.getPlugin().deleteLogs()); view.findViewById(R.id.log_delete).setOnClickListener(view1 -> MaintenancePlugin.getPlugin().deleteLogs());
view.findViewById(R.id.nav_resetdb).setOnClickListener(view1 -> new AlertDialog.Builder(f.getContext()) view.findViewById(R.id.nav_resetdb).setOnClickListener(view1 ->
.setTitle(R.string.nav_resetdb) OKDialog.showConfirmation(getContext(), MainApp.gs(R.string.maintenance), MainApp.gs(R.string.reset_db_confirm), () -> {
.setMessage(R.string.reset_db_confirm)
.setNegativeButton(android.R.string.cancel, null)
.setPositiveButton(android.R.string.ok, (dialog, which) -> {
MainApp.getDbHelper().resetDatabases(); MainApp.getDbHelper().resetDatabases();
// should be handled by Plugin-Interface and // should be handled by Plugin-Interface and
// additional service interface and plugin registry // additional service interface and plugin registry
FoodPlugin.getPlugin().getService().resetFood(); FoodPlugin.getPlugin().getService().resetFood();
TreatmentsPlugin.getPlugin().getService().resetTreatments(); TreatmentsPlugin.getPlugin().getService().resetTreatments();
}) })
.create() );
.show());
view.findViewById(R.id.nav_export).setOnClickListener(view1 -> { view.findViewById(R.id.nav_export).setOnClickListener(view1 -> {
// start activity for checking permissions... // start activity for checking permissions...
ImportExportPrefs.verifyStoragePermissions(f); ImportExportPrefs.verifyStoragePermissions(this);
ImportExportPrefs.exportSharedPreferences(f); ImportExportPrefs.exportSharedPreferences(this);
}); });
view.findViewById(R.id.nav_import).setOnClickListener(view1 -> { view.findViewById(R.id.nav_import).setOnClickListener(view1 -> {
// start activity for checking permissions... // start activity for checking permissions...
ImportExportPrefs.verifyStoragePermissions(f); ImportExportPrefs.verifyStoragePermissions(this);
ImportExportPrefs.importSharedPreferences(f); ImportExportPrefs.importSharedPreferences(this);
}); });
view.findViewById(R.id.nav_logsettings).setOnClickListener(view1 -> { view.findViewById(R.id.nav_logsettings).setOnClickListener(view1 -> {
startActivity(new Intent(getActivity(), LogSettingActivity.class)); startActivity(new Intent(getActivity(), LogSettingActivity.class));
}); });
return view; return view;
} }

View file

@ -1,9 +1,6 @@
package info.nightscout.androidaps.plugins.general.nsclient; package info.nightscout.androidaps.plugins.general.nsclient;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Paint; import android.graphics.Paint;
import android.os.Bundle; import android.os.Bundle;
import android.text.Html; import android.text.Html;
@ -25,6 +22,7 @@ import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientN
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientRestart; import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientRestart;
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientUpdateGUI; import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientUpdateGUI;
import info.nightscout.androidaps.utils.FabricPrivacy; import info.nightscout.androidaps.utils.FabricPrivacy;
import info.nightscout.androidaps.utils.OKDialog;
import info.nightscout.androidaps.utils.SP; import info.nightscout.androidaps.utils.SP;
import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable; import io.reactivex.disposables.CompositeDisposable;
@ -113,20 +111,11 @@ public class NSClientFragment extends Fragment implements View.OnClickListener,
NSClientPlugin.getPlugin().clearLog(); NSClientPlugin.getPlugin().clearLog();
break; break;
case R.id.nsclientinternal_clearqueue: case R.id.nsclientinternal_clearqueue:
final Context context = getContext(); OKDialog.showConfirmation(getContext(),MainApp.gs(R.string.nsclientinternal), MainApp.gs(R.string.clearqueueconfirm), () -> {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(MainApp.gs(R.string.confirmation));
builder.setMessage("Clear queue? All data in queue will be lost!");
builder.setPositiveButton(MainApp.gs(R.string.ok), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
UploadQueue.clearQueue(); UploadQueue.clearQueue();
updateGui(); updateGui();
FabricPrivacy.getInstance().logCustom("NSClientClearQueue"); FabricPrivacy.getInstance().logCustom("NSClientClearQueue");
}
}); });
builder.setNegativeButton(MainApp.gs(R.string.cancel), null);
builder.show();
break; break;
case R.id.nsclientinternal_showqueue: case R.id.nsclientinternal_showqueue:
RxBus.INSTANCE.send(new EventNSClientNewLog("QUEUE", NSClientPlugin.getPlugin().queue().textList())); RxBus.INSTANCE.send(new EventNSClientNewLog("QUEUE", NSClientPlugin.getPlugin().queue().textList()));

View file

@ -32,6 +32,8 @@ import info.nightscout.androidaps.interfaces.PluginDescription;
import info.nightscout.androidaps.interfaces.PluginType; import info.nightscout.androidaps.interfaces.PluginType;
import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.plugins.bus.RxBus; import info.nightscout.androidaps.plugins.bus.RxBus;
import info.nightscout.androidaps.plugins.general.nsclient.data.AlarmAck;
import info.nightscout.androidaps.plugins.general.nsclient.data.NSAlarm;
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientNewLog; import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientNewLog;
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientStatus; import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientStatus;
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientUpdateGUI; import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientUpdateGUI;
@ -250,4 +252,25 @@ public class NSClientPlugin extends PluginBase {
public boolean hasWritePermission() { public boolean hasWritePermission() {
return nsClientService.hasWriteAuth; return nsClientService.hasWriteAuth;
} }
public void handleClearAlarm(NSAlarm originalAlarm, long silenceTimeInMsec) {
if (!isEnabled(PluginType.GENERAL)) {
return;
}
if (SP.getBoolean(R.string.key_ns_noupload, false)) {
if (L.isEnabled(L.NSCLIENT))
log.debug("Upload disabled. Message dropped");
return;
}
AlarmAck ack = new AlarmAck();
ack.level = originalAlarm.getLevel();
ack.group = originalAlarm.getGroup();
ack.silenceTime = silenceTimeInMsec;
if (nsClientService != null)
nsClientService.sendAlarmAck(ack);
}
} }

View file

@ -1,14 +1,13 @@
package info.nightscout.androidaps.plugins.general.nsclient; package info.nightscout.androidaps.plugins.general.nsclient;
import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.pm.ResolveInfo; import android.content.pm.ResolveInfo;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.json.JSONArray; import org.json.JSONArray;
@ -24,22 +23,23 @@ import java.util.Locale;
import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R; import info.nightscout.androidaps.R;
import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
import info.nightscout.androidaps.services.Intents;
import info.nightscout.androidaps.data.DetailedBolusInfo; import info.nightscout.androidaps.data.DetailedBolusInfo;
import info.nightscout.androidaps.data.IobTotal;
import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.db.BgReading; import info.nightscout.androidaps.db.BgReading;
import info.nightscout.androidaps.db.CareportalEvent; import info.nightscout.androidaps.db.CareportalEvent;
import info.nightscout.androidaps.db.DbRequest;
import info.nightscout.androidaps.db.ExtendedBolus; import info.nightscout.androidaps.db.ExtendedBolus;
import info.nightscout.androidaps.db.ProfileSwitch; import info.nightscout.androidaps.db.ProfileSwitch;
import info.nightscout.androidaps.db.TempTarget; import info.nightscout.androidaps.db.TempTarget;
import info.nightscout.androidaps.db.TemporaryBasal; import info.nightscout.androidaps.db.TemporaryBasal;
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.plugins.aps.loop.APSResult; import info.nightscout.androidaps.plugins.aps.loop.APSResult;
import info.nightscout.androidaps.plugins.aps.loop.DeviceStatus; import info.nightscout.androidaps.plugins.aps.loop.DeviceStatus;
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin; import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin;
import info.nightscout.androidaps.plugins.general.nsclient.data.DbLogger; import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin;
import info.nightscout.androidaps.utils.BatteryLevel; import info.nightscout.androidaps.utils.BatteryLevel;
import info.nightscout.androidaps.utils.DateUtil; import info.nightscout.androidaps.utils.DateUtil;
import info.nightscout.androidaps.utils.SP; import info.nightscout.androidaps.utils.SP;
@ -53,7 +53,6 @@ public class NSUpload {
public static void uploadTempBasalStartAbsolute(TemporaryBasal temporaryBasal, Double originalExtendedAmount) { public static void uploadTempBasalStartAbsolute(TemporaryBasal temporaryBasal, Double originalExtendedAmount) {
try { try {
Context context = MainApp.instance().getApplicationContext();
JSONObject data = new JSONObject(); JSONObject data = new JSONObject();
data.put("eventType", CareportalEvent.TEMPBASAL); data.put("eventType", CareportalEvent.TEMPBASAL);
data.put("duration", temporaryBasal.durationInMinutes); data.put("duration", temporaryBasal.durationInMinutes);
@ -65,15 +64,7 @@ public class NSUpload {
data.put("enteredBy", "openaps://" + MainApp.gs(R.string.app_name)); data.put("enteredBy", "openaps://" + MainApp.gs(R.string.app_name));
if (originalExtendedAmount != null) if (originalExtendedAmount != null)
data.put("originalExtendedAmount", originalExtendedAmount); // for back synchronization data.put("originalExtendedAmount", originalExtendedAmount); // for back synchronization
Bundle bundle = new Bundle(); UploadQueue.add(new DbRequest("dbAdd", "treatments", data));
bundle.putString("action", "dbAdd");
bundle.putString("collection", "treatments");
bundle.putString("data", data.toString());
Intent intent = new Intent(Intents.ACTION_DATABASE);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
DbLogger.dbAdd(intent, data.toString());
} catch (JSONException e) { } catch (JSONException e) {
log.error("Unhandled exception", e); log.error("Unhandled exception", e);
} }
@ -96,7 +87,6 @@ public class NSUpload {
uploadTempBasalStartAbsolute(t, null); uploadTempBasalStartAbsolute(t, null);
} }
} else { } else {
Context context = MainApp.instance().getApplicationContext();
JSONObject data = new JSONObject(); JSONObject data = new JSONObject();
data.put("eventType", CareportalEvent.TEMPBASAL); data.put("eventType", CareportalEvent.TEMPBASAL);
data.put("duration", temporaryBasal.durationInMinutes); data.put("duration", temporaryBasal.durationInMinutes);
@ -107,15 +97,7 @@ public class NSUpload {
data.put("pumpId", temporaryBasal.pumpId); data.put("pumpId", temporaryBasal.pumpId);
data.put("created_at", DateUtil.toISOString(temporaryBasal.date)); data.put("created_at", DateUtil.toISOString(temporaryBasal.date));
data.put("enteredBy", "openaps://" + MainApp.gs(R.string.app_name)); data.put("enteredBy", "openaps://" + MainApp.gs(R.string.app_name));
Bundle bundle = new Bundle(); UploadQueue.add(new DbRequest("dbAdd", "treatments", data));
bundle.putString("action", "dbAdd");
bundle.putString("collection", "treatments");
bundle.putString("data", data.toString());
Intent intent = new Intent(Intents.ACTION_DATABASE);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
DbLogger.dbAdd(intent, data.toString());
} }
} catch (JSONException e) { } catch (JSONException e) {
log.error("Unhandled exception", e); log.error("Unhandled exception", e);
@ -124,7 +106,6 @@ public class NSUpload {
public static void uploadTempBasalEnd(long time, boolean isFakedTempBasal, long pumpId) { public static void uploadTempBasalEnd(long time, boolean isFakedTempBasal, long pumpId) {
try { try {
Context context = MainApp.instance().getApplicationContext();
JSONObject data = new JSONObject(); JSONObject data = new JSONObject();
data.put("eventType", CareportalEvent.TEMPBASAL); data.put("eventType", CareportalEvent.TEMPBASAL);
data.put("created_at", DateUtil.toISOString(time)); data.put("created_at", DateUtil.toISOString(time));
@ -133,15 +114,7 @@ public class NSUpload {
data.put("isFakedTempBasal", isFakedTempBasal); data.put("isFakedTempBasal", isFakedTempBasal);
if (pumpId != 0) if (pumpId != 0)
data.put("pumpId", pumpId); data.put("pumpId", pumpId);
Bundle bundle = new Bundle(); UploadQueue.add(new DbRequest("dbAdd", "treatments", data));
bundle.putString("action", "dbAdd");
bundle.putString("collection", "treatments");
bundle.putString("data", data.toString());
Intent intent = new Intent(Intents.ACTION_DATABASE);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
DbLogger.dbAdd(intent, data.toString());
} catch (JSONException e) { } catch (JSONException e) {
log.error("Unhandled exception", e); log.error("Unhandled exception", e);
} }
@ -149,7 +122,6 @@ public class NSUpload {
public static void uploadExtendedBolus(ExtendedBolus extendedBolus) { public static void uploadExtendedBolus(ExtendedBolus extendedBolus) {
try { try {
Context context = MainApp.instance().getApplicationContext();
JSONObject data = new JSONObject(); JSONObject data = new JSONObject();
data.put("eventType", CareportalEvent.COMBOBOLUS); data.put("eventType", CareportalEvent.COMBOBOLUS);
data.put("duration", extendedBolus.durationInMinutes); data.put("duration", extendedBolus.durationInMinutes);
@ -161,15 +133,7 @@ public class NSUpload {
data.put("pumpId", extendedBolus.pumpId); data.put("pumpId", extendedBolus.pumpId);
data.put("created_at", DateUtil.toISOString(extendedBolus.date)); data.put("created_at", DateUtil.toISOString(extendedBolus.date));
data.put("enteredBy", "openaps://" + MainApp.gs(R.string.app_name)); data.put("enteredBy", "openaps://" + MainApp.gs(R.string.app_name));
Bundle bundle = new Bundle(); UploadQueue.add(new DbRequest("dbAdd", "treatments", data));
bundle.putString("action", "dbAdd");
bundle.putString("collection", "treatments");
bundle.putString("data", data.toString());
Intent intent = new Intent(Intents.ACTION_DATABASE);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
DbLogger.dbAdd(intent, data.toString());
} catch (JSONException e) { } catch (JSONException e) {
log.error("Unhandled exception", e); log.error("Unhandled exception", e);
} }
@ -177,7 +141,6 @@ public class NSUpload {
public static void uploadExtendedBolusEnd(long time, long pumpId) { public static void uploadExtendedBolusEnd(long time, long pumpId) {
try { try {
Context context = MainApp.instance().getApplicationContext();
JSONObject data = new JSONObject(); JSONObject data = new JSONObject();
data.put("eventType", CareportalEvent.COMBOBOLUS); data.put("eventType", CareportalEvent.COMBOBOLUS);
data.put("duration", 0); data.put("duration", 0);
@ -189,15 +152,7 @@ public class NSUpload {
data.put("enteredBy", "openaps://" + MainApp.gs(R.string.app_name)); data.put("enteredBy", "openaps://" + MainApp.gs(R.string.app_name));
if (pumpId != 0) if (pumpId != 0)
data.put("pumpId", pumpId); data.put("pumpId", pumpId);
Bundle bundle = new Bundle(); UploadQueue.add(new DbRequest("dbAdd", "treatments", data));
bundle.putString("action", "dbAdd");
bundle.putString("collection", "treatments");
bundle.putString("data", data.toString());
Intent intent = new Intent(Intents.ACTION_DATABASE);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
DbLogger.dbAdd(intent, data.toString());
} catch (JSONException e) { } catch (JSONException e) {
log.error("Unhandled exception", e); log.error("Unhandled exception", e);
} }
@ -246,7 +201,12 @@ public class NSUpload {
} }
} else { } else {
if (L.isEnabled(L.NSCLIENT)) if (L.isEnabled(L.NSCLIENT))
log.debug("OpenAPS data too old to upload"); log.debug("OpenAPS data too old to upload, sending iob only");
IobTotal[] iob = IobCobCalculatorPlugin.getPlugin().calculateIobArrayInDia(profile);
if (iob.length > 0) {
deviceStatus.iob = iob[0].json();
deviceStatus.iob.put("time", DateUtil.toISOString(DateUtil.now()));
}
} }
deviceStatus.device = "openaps://" + Build.MANUFACTURER + " " + Build.MODEL; deviceStatus.device = "openaps://" + Build.MANUFACTURER + " " + Build.MODEL;
JSONObject pumpstatus = ConfigBuilderPlugin.getPlugin().getActivePump().getJSONStatus(profile, profileName); JSONObject pumpstatus = ConfigBuilderPlugin.getPlugin().getActivePump().getJSONStatus(profile, profileName);
@ -258,16 +218,7 @@ public class NSUpload {
deviceStatus.uploaderBattery = batteryLevel; deviceStatus.uploaderBattery = batteryLevel;
deviceStatus.created_at = DateUtil.toISOString(new Date()); deviceStatus.created_at = DateUtil.toISOString(new Date());
Context context = MainApp.instance().getApplicationContext(); UploadQueue.add(new DbRequest("dbAdd", "devicestatus", deviceStatus.mongoRecord()));
Bundle bundle = new Bundle();
bundle.putString("action", "dbAdd");
bundle.putString("collection", "devicestatus");
bundle.putString("data", deviceStatus.mongoRecord().toString());
Intent intent = new Intent(Intents.ACTION_DATABASE);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
DbLogger.dbAdd(intent, deviceStatus.mongoRecord().toString());
} catch (JSONException e) { } catch (JSONException e) {
log.error("Unhandled exception", e); log.error("Unhandled exception", e);
} }
@ -333,17 +284,7 @@ public class NSUpload {
try { try {
JSONObject data = getJson(profileSwitch); JSONObject data = getJson(profileSwitch);
if (profileSwitch._id != null) { if (profileSwitch._id != null) {
Context context = MainApp.instance().getApplicationContext(); UploadQueue.add(new DbRequest("dbUpdate", "treatments", profileSwitch._id, data));
Bundle bundle = new Bundle();
bundle.putString("action", "dbUpdate");
bundle.putString("collection", "treatments");
bundle.putString("data", data.toString());
bundle.putString("_id", profileSwitch._id);
Intent intent = new Intent(Intents.ACTION_DATABASE);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
DbLogger.dbAdd(intent, data.toString());
} }
} catch (JSONException e) { } catch (JSONException e) {
log.error("Unhandled exception", e); log.error("Unhandled exception", e);
@ -382,16 +323,7 @@ public class NSUpload {
prebolus.put("created_at", DateUtil.toISOString(preBolusDate)); prebolus.put("created_at", DateUtil.toISOString(preBolusDate));
uploadCareportalEntryToNS(prebolus); uploadCareportalEntryToNS(prebolus);
} }
Context context = MainApp.instance().getApplicationContext(); UploadQueue.add(new DbRequest("dbAdd", "treatments", data));
Bundle bundle = new Bundle();
bundle.putString("action", "dbAdd");
bundle.putString("collection", "treatments");
bundle.putString("data", data.toString());
Intent intent = new Intent(Intents.ACTION_DATABASE);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
DbLogger.dbAdd(intent, data.toString());
} catch (Exception e) { } catch (Exception e) {
log.error("Unhandled exception", e); log.error("Unhandled exception", e);
} }
@ -399,40 +331,17 @@ public class NSUpload {
} }
public static void removeCareportalEntryFromNS(String _id) { public static void removeCareportalEntryFromNS(String _id) {
try { UploadQueue.add(new DbRequest("dbRemove", "treatments", _id));
Context context = MainApp.instance().getApplicationContext();
Bundle bundle = new Bundle();
bundle.putString("action", "dbRemove");
bundle.putString("collection", "treatments");
bundle.putString("_id", _id);
Intent intent = new Intent(Intents.ACTION_DATABASE);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
DbLogger.dbRemove(intent, _id);
} catch (Exception e) {
log.error("Unhandled exception", e);
}
} }
public static void uploadOpenAPSOffline(double durationInMinutes) { public static void uploadOpenAPSOffline(double durationInMinutes) {
try { try {
Context context = MainApp.instance().getApplicationContext();
JSONObject data = new JSONObject(); JSONObject data = new JSONObject();
data.put("eventType", "OpenAPS Offline"); data.put("eventType", "OpenAPS Offline");
data.put("duration", durationInMinutes); data.put("duration", durationInMinutes);
data.put("created_at", DateUtil.toISOString(new Date())); data.put("created_at", DateUtil.toISOString(new Date()));
data.put("enteredBy", "openaps://" + MainApp.gs(R.string.app_name)); data.put("enteredBy", "openaps://" + MainApp.gs(R.string.app_name));
Bundle bundle = new Bundle(); UploadQueue.add(new DbRequest("dbAdd", "treatments", data));
bundle.putString("action", "dbAdd");
bundle.putString("collection", "treatments");
bundle.putString("data", data.toString());
Intent intent = new Intent(Intents.ACTION_DATABASE);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
DbLogger.dbAdd(intent, data.toString());
} catch (JSONException e) { } catch (JSONException e) {
log.error("Unhandled exception", e); log.error("Unhandled exception", e);
} }
@ -443,10 +352,6 @@ public class NSUpload {
} }
public static void uploadError(String error, Date date) { public static void uploadError(String error, Date date) {
Context context = MainApp.instance().getApplicationContext();
Bundle bundle = new Bundle();
bundle.putString("action", "dbAdd");
bundle.putString("collection", "treatments");
JSONObject data = new JSONObject(); JSONObject data = new JSONObject();
try { try {
data.put("eventType", "Announcement"); data.put("eventType", "Announcement");
@ -457,19 +362,10 @@ public class NSUpload {
} catch (JSONException e) { } catch (JSONException e) {
log.error("Unhandled exception", e); log.error("Unhandled exception", e);
} }
bundle.putString("data", data.toString()); UploadQueue.add(new DbRequest("dbAdd", "treatments", data));
Intent intent = new Intent(Intents.ACTION_DATABASE);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
DbLogger.dbAdd(intent, data.toString());
} }
public static void uploadBg(BgReading reading, String source) { public static void uploadBg(BgReading reading, String source) {
Context context = MainApp.instance().getApplicationContext();
Bundle bundle = new Bundle();
bundle.putString("action", "dbAdd");
bundle.putString("collection", "entries");
JSONObject data = new JSONObject(); JSONObject data = new JSONObject();
try { try {
data.put("device", source); data.put("device", source);
@ -481,20 +377,11 @@ public class NSUpload {
} catch (JSONException e) { } catch (JSONException e) {
log.error("Unhandled exception", e); log.error("Unhandled exception", e);
} }
bundle.putString("data", data.toString()); UploadQueue.add(new DbRequest("dbAdd", "entries", data));
Intent intent = new Intent(Intents.ACTION_DATABASE);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
DbLogger.dbAdd(intent, data.toString());
} }
public static void uploadAppStart() { public static void uploadAppStart() {
if (SP.getBoolean(R.string.key_ns_logappstartedevent, true)) { if (SP.getBoolean(R.string.key_ns_logappstartedevent, true)) {
Context context = MainApp.instance().getApplicationContext();
Bundle bundle = new Bundle();
bundle.putString("action", "dbAdd");
bundle.putString("collection", "treatments");
JSONObject data = new JSONObject(); JSONObject data = new JSONObject();
try { try {
data.put("eventType", "Note"); data.put("eventType", "Note");
@ -503,35 +390,17 @@ public class NSUpload {
} catch (JSONException e) { } catch (JSONException e) {
log.error("Unhandled exception", e); log.error("Unhandled exception", e);
} }
bundle.putString("data", data.toString()); UploadQueue.add(new DbRequest("dbAdd", "treatments", data));
Intent intent = new Intent(Intents.ACTION_DATABASE);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
DbLogger.dbAdd(intent, data.toString());
} }
} }
public static void uploadProfileStore(JSONObject profileStore) { public static void uploadProfileStore(JSONObject profileStore) {
if (SP.getBoolean(R.string.key_ns_uploadlocalprofile, false)) { if (SP.getBoolean(R.string.key_ns_uploadlocalprofile, false)) {
Context context = MainApp.instance().getApplicationContext(); UploadQueue.add(new DbRequest("dbAdd", "profile", String.valueOf(profileStore)));
Bundle bundle = new Bundle();
bundle.putString("action", "dbAdd");
bundle.putString("collection", "profile");
bundle.putString("data", String.valueOf(profileStore));
Intent intent = new Intent(Intents.ACTION_DATABASE);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
DbLogger.dbAdd(intent, String.valueOf(profileStore));
} }
} }
public static void uploadEvent(String careportalEvent, long time, @Nullable String notes) { public static void uploadEvent(String careportalEvent, long time, @Nullable String notes) {
Context context = MainApp.instance().getApplicationContext();
Bundle bundle = new Bundle();
bundle.putString("action", "dbAdd");
bundle.putString("collection", "treatments");
JSONObject data = new JSONObject(); JSONObject data = new JSONObject();
try { try {
data.put("eventType", careportalEvent); data.put("eventType", careportalEvent);
@ -543,26 +412,12 @@ public class NSUpload {
} catch (JSONException e) { } catch (JSONException e) {
log.error("Unhandled exception", e); log.error("Unhandled exception", e);
} }
bundle.putString("data", data.toString()); UploadQueue.add(new DbRequest("dbAdd", "treatments", data));
Intent intent = new Intent(Intents.ACTION_DATABASE);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
DbLogger.dbAdd(intent, data.toString());
} }
public static void removeFoodFromNS(String _id) { public static void removeFoodFromNS(String _id) {
try { try {
Context context = MainApp.instance().getApplicationContext(); UploadQueue.add(new DbRequest("dbRemove", "food", _id));
Bundle bundle = new Bundle();
bundle.putString("action", "dbRemove");
bundle.putString("collection", "food");
bundle.putString("_id", _id);
Intent intent = new Intent(Intents.ACTION_DATABASE);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
DbLogger.dbRemove(intent, _id);
} catch (Exception e) { } catch (Exception e) {
log.error("Unhandled exception", e); log.error("Unhandled exception", e);
} }

View file

@ -1,43 +0,0 @@
package info.nightscout.androidaps.plugins.general.nsclient.broadcasts;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.services.Intents;
import info.nightscout.androidaps.plugins.general.nsclient.data.NSAlarm;
import info.nightscout.androidaps.utils.SP;
/**
* Created by mike on 11.06.2017.
*/
public class BroadcastAckAlarm {
public static void handleClearAlarm(NSAlarm originalAlarm, Context context, long silenceTimeInMsec) {
Bundle bundle = new Bundle();
bundle.putInt("level", originalAlarm.getLevel());
bundle.putString("group", originalAlarm.getGroup());
bundle.putLong("silenceTime", silenceTimeInMsec);
Intent intent = new Intent(Intents.ACTION_ACK_ALARM);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent);
if(SP.getBoolean(R.string.key_nsclient_localbroadcasts, false)) {
bundle = new Bundle();
bundle.putInt("level", originalAlarm.getLevel());
bundle.putString("group", originalAlarm.getGroup());
bundle.putLong("silenceTime", silenceTimeInMsec);
intent = new Intent(Intents.ACTION_ACK_ALARM);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
context.sendBroadcast(intent);
}
}
}

View file

@ -25,12 +25,11 @@ import info.nightscout.androidaps.utils.SP;
public class BroadcastTreatment { public class BroadcastTreatment {
private static Logger log = LoggerFactory.getLogger(L.NSCLIENT); private static Logger log = LoggerFactory.getLogger(L.NSCLIENT);
public static void handleNewTreatment(JSONObject treatment, boolean isDelta, boolean isLocalBypass) { public static void handleNewTreatment(JSONObject treatment, boolean isDelta) {
Bundle bundle = new Bundle(); Bundle bundle = new Bundle();
bundle.putString("treatment", treatment.toString()); bundle.putString("treatment", treatment.toString());
bundle.putBoolean("delta", isDelta); bundle.putBoolean("delta", isDelta);
bundle.putBoolean("islocal", isLocalBypass);
Intent intent = new Intent(Intents.ACTION_NEW_TREATMENT); Intent intent = new Intent(Intents.ACTION_NEW_TREATMENT);
intent.putExtras(bundle); intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);

View file

@ -1,43 +0,0 @@
package info.nightscout.androidaps.plugins.general.nsclient.data;
import android.content.Intent;
import android.content.pm.ResolveInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.utils.ToastUtils;
/**
* Created by mike on 02.07.2016.
*/
public class DbLogger {
private static Logger log = LoggerFactory.getLogger(L.NSCLIENT);
public static void dbAdd(Intent intent, String data) {
List<ResolveInfo> q = MainApp.instance().getApplicationContext().getPackageManager().queryBroadcastReceivers(intent, 0);
if (q.size() < 1) {
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.nsclientnotinstalled));
log.error("DBADD No receivers");
} else if (L.isEnabled(L.NSCLIENT)) {
if (L.isEnabled(L.NSCLIENT))
log.debug("DBADD dbAdd " + q.size() + " receivers " + data);
}
}
public static void dbRemove(Intent intent, String data) {
List<ResolveInfo> q = MainApp.instance().getApplicationContext().getPackageManager().queryBroadcastReceivers(intent, 0);
if (q.size() < 1) {
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.nsclientnotinstalled));
log.error("DBREMOVE No receivers");
} else if (L.isEnabled(L.NSCLIENT)) {
if (L.isEnabled(L.NSCLIENT))
log.debug("DBREMOVE dbRemove " + q.size() + " receivers " + data);
}
}
}

View file

@ -407,7 +407,7 @@ public class NSDeviceStatus {
} }
Uploader uploader = uploaders.get(device); Uploader uploader = uploaders.get(device);
// check if this is new data // check if this is new data
if (clock != 0 && (uploader != null && clock > uploader.clock || uploader == null)) { if (clock != 0 && battery != null && (uploader != null && clock > uploader.clock || uploader == null)) {
if (uploader == null) if (uploader == null)
uploader = new Uploader(); uploader = new Uploader();
uploader.battery = battery; uploader.battery = battery;

View file

@ -1,60 +0,0 @@
package info.nightscout.androidaps.plugins.general.nsclient.receivers;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.PowerManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.interfaces.PluginType;
import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.plugins.general.nsclient.NSClientPlugin;
import info.nightscout.androidaps.plugins.general.nsclient.data.AlarmAck;
import info.nightscout.androidaps.plugins.general.nsclient.services.NSClientService;
import info.nightscout.androidaps.utils.SP;
public class AckAlarmReceiver extends BroadcastReceiver {
private static Logger log = LoggerFactory.getLogger(L.NSCLIENT);
@Override
public void onReceive(Context context, Intent intent) {
PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
AckAlarmReceiver.class.getSimpleName());
NSClientPlugin nsClientPlugin = NSClientPlugin.getPlugin();
if (!nsClientPlugin.isEnabled(PluginType.GENERAL)) {
return;
}
if (SP.getBoolean(R.string.key_ns_noupload, false)) {
if (L.isEnabled(L.NSCLIENT))
log.debug("Upload disabled. Message dropped");
return;
}
wakeLock.acquire();
try {
Bundle bundles = intent.getExtras();
if (bundles == null) return;
if (!bundles.containsKey("level")) return;
if (!bundles.containsKey("group")) return;
if (!bundles.containsKey("silenceTime")) return;
AlarmAck ack = new AlarmAck();
ack.level = bundles.getInt("level");
ack.group = bundles.getString("group");
ack.silenceTime = bundles.getLong("silenceTime");
NSClientService nsClientService = nsClientPlugin.nsClientService;
if (nsClientService != null)
nsClientService.sendAlarmAck(ack);
} finally {
wakeLock.release();
}
}
}

View file

@ -1,147 +0,0 @@
package info.nightscout.androidaps.plugins.general.nsclient.receivers;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.PowerManager;
import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.db.DbRequest;
import info.nightscout.androidaps.interfaces.PluginType;
import info.nightscout.androidaps.logging.BundleLogger;
import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.plugins.general.nsclient.NSClientPlugin;
import info.nightscout.androidaps.plugins.general.nsclient.UploadQueue;
import info.nightscout.androidaps.plugins.general.nsclient.broadcasts.BroadcastTreatment;
import info.nightscout.androidaps.utils.DateUtil;
import info.nightscout.androidaps.utils.SP;
public class DBAccessReceiver extends BroadcastReceiver {
private static Logger log = LoggerFactory.getLogger(L.NSCLIENT);
@Override
public void onReceive(Context context, Intent intent) {
PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
DBAccessReceiver.class.getSimpleName());
wakeLock.acquire();
try {
Bundle bundles = intent.getExtras();
if (bundles == null) return;
if (!bundles.containsKey("action")) return;
if (L.isEnabled(L.NSCLIENT))
log.debug(BundleLogger.log(bundles));
String collection = null;
String _id = null;
JSONObject data = null;
String action = bundles.getString("action");
try {
collection = bundles.getString("collection");
} catch (Exception e) {
log.error("Unhandled exception", e);
return;
}
try {
if (!action.equals("dbAdd"))
_id = bundles.getString("_id");
} catch (Exception e) {
log.error("Unhandled exception", e);
return;
}
try {
if (!action.equals("dbRemove"))
data = new JSONObject(bundles.getString("data"));
} catch (Exception e) {
log.error("Unhandled exception", e);
return;
}
if (data == null && !action.equals("dbRemove") || _id == null && action.equals("dbRemove")) {
log.error("DBACCESS no data inside record");
return;
}
if (action.equals("dbRemove")) {
data = new JSONObject();
}
// mark by id
Long nsclientid = System.currentTimeMillis();
try {
data.put("NSCLIENT_ID", nsclientid);
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
if (!isAllowedCollection(collection)) {
log.error("DBACCESS wrong collection specified");
return;
}
if (action.equals("dbRemove")) {
if (shouldUpload()) {
DbRequest dbr = new DbRequest(action, collection, nsclientid.toString(), _id);
UploadQueue.add(dbr);
}
} else if (action.equals("dbUpdate")) {
if (shouldUpload()) {
DbRequest dbr = new DbRequest(action, collection, nsclientid.toString(), _id, data);
UploadQueue.add(dbr);
}
} else {
DbRequest dbr = new DbRequest(action, collection, nsclientid.toString(), data);
// this is not used as mongo _id but only for searching in UploadQueue database
// if record has to be removed from queue before upload
dbr._id = nsclientid.toString();
if (shouldUpload()) {
UploadQueue.add(dbr);
}
if (collection.equals("treatments")) {
generateTreatmentOfflineBroadcast(dbr);
}
}
} finally {
wakeLock.release();
}
}
public boolean shouldUpload() {
NSClientPlugin nsClientPlugin = NSClientPlugin.getPlugin();
return nsClientPlugin.isEnabled(PluginType.GENERAL) && !SP.getBoolean(R.string.key_ns_noupload, false);
}
public void generateTreatmentOfflineBroadcast(DbRequest request) {
if (request.action.equals("dbAdd")) {
try {
JSONObject data = new JSONObject(request.data);
data.put("mills", DateUtil.fromISODateString(data.getString("created_at")).getTime());
data.put("_id", data.get("NSCLIENT_ID")); // this is only fake id
BroadcastTreatment.handleNewTreatment(data, false, true);
} catch (Exception e) {
log.error("Unhadled exception", e);
}
}
}
private boolean isAllowedCollection(String collection) {
// "treatments" || "entries" || "devicestatus" || "profile" || "food"
if (collection.equals("treatments")) return true;
if (collection.equals("entries")) return true;
if (collection.equals("devicestatus")) return true;
if (collection.equals("profile")) return true;
if (collection.equals("food")) return true;
return false;
}
}

View file

@ -61,6 +61,14 @@ import info.nightscout.androidaps.db.ExtendedBolus;
import info.nightscout.androidaps.db.Source; import info.nightscout.androidaps.db.Source;
import info.nightscout.androidaps.db.TempTarget; import info.nightscout.androidaps.db.TempTarget;
import info.nightscout.androidaps.db.TemporaryBasal; import info.nightscout.androidaps.db.TemporaryBasal;
import info.nightscout.androidaps.dialogs.CalibrationDialog;
import info.nightscout.androidaps.dialogs.CarbsDialog;
import info.nightscout.androidaps.dialogs.InsulinDialog;
import info.nightscout.androidaps.dialogs.ProfileSwitchDialog;
import info.nightscout.androidaps.dialogs.ProfileViewerDialog;
import info.nightscout.androidaps.dialogs.TempTargetDialog;
import info.nightscout.androidaps.dialogs.TreatmentDialog;
import info.nightscout.androidaps.dialogs.WizardDialog;
import info.nightscout.androidaps.events.EventAcceptOpenLoopChange; import info.nightscout.androidaps.events.EventAcceptOpenLoopChange;
import info.nightscout.androidaps.events.EventCareportalEventChange; import info.nightscout.androidaps.events.EventCareportalEventChange;
import info.nightscout.androidaps.events.EventExtendedBolusChange; import info.nightscout.androidaps.events.EventExtendedBolusChange;
@ -84,16 +92,9 @@ import info.nightscout.androidaps.plugins.bus.RxBus;
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
import info.nightscout.androidaps.plugins.general.careportal.CareportalFragment; import info.nightscout.androidaps.plugins.general.careportal.CareportalFragment;
import info.nightscout.androidaps.plugins.general.careportal.Dialogs.NewNSTreatmentDialog;
import info.nightscout.androidaps.plugins.general.careportal.OptionsToShow;
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload; import info.nightscout.androidaps.plugins.general.nsclient.NSUpload;
import info.nightscout.androidaps.plugins.general.nsclient.data.NSDeviceStatus; import info.nightscout.androidaps.plugins.general.nsclient.data.NSDeviceStatus;
import info.nightscout.androidaps.plugins.general.overview.activities.QuickWizardListActivity; import info.nightscout.androidaps.plugins.general.overview.activities.QuickWizardListActivity;
import info.nightscout.androidaps.plugins.general.overview.dialogs.CalibrationDialog;
import info.nightscout.androidaps.plugins.general.overview.dialogs.NewCarbsDialog;
import info.nightscout.androidaps.plugins.general.overview.dialogs.NewInsulinDialog;
import info.nightscout.androidaps.plugins.general.overview.dialogs.NewTreatmentDialog;
import info.nightscout.androidaps.plugins.general.overview.dialogs.WizardDialog;
import info.nightscout.androidaps.plugins.general.overview.graphData.GraphData; import info.nightscout.androidaps.plugins.general.overview.graphData.GraphData;
import info.nightscout.androidaps.plugins.general.wear.ActionStringHandler; import info.nightscout.androidaps.plugins.general.wear.ActionStringHandler;
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensData; import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensData;
@ -105,7 +106,6 @@ import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventIobCa
import info.nightscout.androidaps.plugins.source.SourceDexcomPlugin; import info.nightscout.androidaps.plugins.source.SourceDexcomPlugin;
import info.nightscout.androidaps.plugins.source.SourceXdripPlugin; import info.nightscout.androidaps.plugins.source.SourceXdripPlugin;
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin; import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
import info.nightscout.androidaps.plugins.treatments.fragments.ProfileViewerDialog;
import info.nightscout.androidaps.queue.Callback; import info.nightscout.androidaps.queue.Callback;
import info.nightscout.androidaps.utils.BolusWizard; import info.nightscout.androidaps.utils.BolusWizard;
import info.nightscout.androidaps.utils.DateUtil; import info.nightscout.androidaps.utils.DateUtil;
@ -744,11 +744,9 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
updateGUI("suspendmenu"); updateGUI("suspendmenu");
return true; return true;
} else if (item.getTitle().equals(MainApp.gs(R.string.careportal_profileswitch))) { } else if (item.getTitle().equals(MainApp.gs(R.string.careportal_profileswitch))) {
NewNSTreatmentDialog newDialog = new NewNSTreatmentDialog(); FragmentManager manager = getFragmentManager();
final OptionsToShow profileswitch = CareportalFragment.PROFILESWITCHDIRECT; if (manager != null)
profileswitch.executeProfileSwitch = true; new ProfileSwitchDialog().show(manager, "Overview");
newDialog.setOptions(profileswitch, R.string.careportal_profileswitch);
newDialog.show(getFragmentManager(), "NewNSTreatmentDialog");
} else if (item.getTitle().equals(MainApp.gs(R.string.danar_viewprofile))) { } else if (item.getTitle().equals(MainApp.gs(R.string.danar_viewprofile))) {
Bundle args = new Bundle(); Bundle args = new Bundle();
args.putLong("time", DateUtil.now()); args.putLong("time", DateUtil.now());
@ -759,44 +757,39 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
if (manager != null) if (manager != null)
pvd.show(manager, "ProfileViewDialog"); pvd.show(manager, "ProfileViewDialog");
} else if (item.getTitle().equals(MainApp.gs(R.string.eatingsoon))) { } else if (item.getTitle().equals(MainApp.gs(R.string.eatingsoon))) {
DefaultValueHelper defHelper = new DefaultValueHelper(); double target = Profile.toMgdl(DefaultValueHelper.determineEatingSoonTT(), ProfileFunctions.getSystemUnits());
double target = Profile.toMgdl(defHelper.determineEatingSoonTT(), ProfileFunctions.getSystemUnits());
TempTarget tempTarget = new TempTarget() TempTarget tempTarget = new TempTarget()
.date(System.currentTimeMillis()) .date(System.currentTimeMillis())
.duration(defHelper.determineEatingSoonTTDuration()) .duration(DefaultValueHelper.determineEatingSoonTTDuration())
.reason(MainApp.gs(R.string.eatingsoon)) .reason(MainApp.gs(R.string.eatingsoon))
.source(Source.USER) .source(Source.USER)
.low(target) .low(target)
.high(target); .high(target);
TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget); TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget);
} else if (item.getTitle().equals(MainApp.gs(R.string.activity))) { } else if (item.getTitle().equals(MainApp.gs(R.string.activity))) {
DefaultValueHelper defHelper = new DefaultValueHelper(); double target = Profile.toMgdl(DefaultValueHelper.determineActivityTT(), ProfileFunctions.getSystemUnits());
double target = Profile.toMgdl(defHelper.determineActivityTT(), ProfileFunctions.getSystemUnits());
TempTarget tempTarget = new TempTarget() TempTarget tempTarget = new TempTarget()
.date(now()) .date(now())
.duration(defHelper.determineActivityTTDuration()) .duration(DefaultValueHelper.determineActivityTTDuration())
.reason(MainApp.gs(R.string.activity)) .reason(MainApp.gs(R.string.activity))
.source(Source.USER) .source(Source.USER)
.low(target) .low(target)
.high(target); .high(target);
TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget); TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget);
} else if (item.getTitle().equals(MainApp.gs(R.string.hypo))) { } else if (item.getTitle().equals(MainApp.gs(R.string.hypo))) {
DefaultValueHelper defHelper = new DefaultValueHelper(); double target = Profile.toMgdl(DefaultValueHelper.determineHypoTT(), ProfileFunctions.getSystemUnits());
double target = Profile.toMgdl(defHelper.determineHypoTT(), ProfileFunctions.getSystemUnits());
TempTarget tempTarget = new TempTarget() TempTarget tempTarget = new TempTarget()
.date(now()) .date(now())
.duration(defHelper.determineHypoTTDuration()) .duration(DefaultValueHelper.determineHypoTTDuration())
.reason(MainApp.gs(R.string.hypo)) .reason(MainApp.gs(R.string.hypo))
.source(Source.USER) .source(Source.USER)
.low(target) .low(target)
.high(target); .high(target);
TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget); TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget);
} else if (item.getTitle().equals(MainApp.gs(R.string.custom))) { } else if (item.getTitle().equals(MainApp.gs(R.string.custom))) {
NewNSTreatmentDialog newTTDialog = new NewNSTreatmentDialog(); FragmentManager manager = getFragmentManager();
final OptionsToShow temptarget = CareportalFragment.TEMPTARGET; if (manager != null)
temptarget.executeTempTarget = true; new TempTargetDialog().show(manager, "Overview");
newTTDialog.setOptions(temptarget, R.string.careportal_temporarytarget);
newTTDialog.show(getFragmentManager(), "NewNSTreatmentDialog");
} else if (item.getTitle().equals(MainApp.gs(R.string.cancel))) { } else if (item.getTitle().equals(MainApp.gs(R.string.cancel))) {
TempTarget tempTarget = new TempTarget() TempTarget tempTarget = new TempTarget()
.source(Source.USER) .source(Source.USER)
@ -818,7 +811,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
FragmentManager manager = getFragmentManager(); FragmentManager manager = getFragmentManager();
// try to fix https://fabric.io/nightscout3/android/apps/info.nightscout.androidaps/issues/5aca7a1536c7b23527eb4be7?time=last-seven-days // try to fix https://fabric.io/nightscout3/android/apps/info.nightscout.androidaps/issues/5aca7a1536c7b23527eb4be7?time=last-seven-days
// https://stackoverflow.com/questions/14860239/checking-if-state-is-saved-before-committing-a-fragmenttransaction // https://stackoverflow.com/questions/14860239/checking-if-state-is-saved-before-committing-a-fragmenttransaction
if (manager.isStateSaved()) if (manager == null || manager.isStateSaved())
return; return;
switch (v.getId()) { switch (v.getId()) {
case R.id.overview_accepttempbutton: case R.id.overview_accepttempbutton:
@ -863,14 +856,13 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
} }
break; break;
case R.id.overview_treatmentbutton: case R.id.overview_treatmentbutton:
NewTreatmentDialog treatmentDialogFragment = new NewTreatmentDialog(); new TreatmentDialog().show(manager, "Overview");
treatmentDialogFragment.show(manager, "TreatmentDialog");
break; break;
case R.id.overview_insulinbutton: case R.id.overview_insulinbutton:
new NewInsulinDialog().show(manager, "InsulinDialog"); new InsulinDialog().show(manager, "Overview");
break; break;
case R.id.overview_carbsbutton: case R.id.overview_carbsbutton:
new NewCarbsDialog().show(manager, "CarbsDialog"); new CarbsDialog().show(manager, "Overview");
break; break;
case R.id.overview_pumpstatus: case R.id.overview_pumpstatus:
if (ConfigBuilderPlugin.getPlugin().getActivePump().isSuspended() || !ConfigBuilderPlugin.getPlugin().getActivePump().isInitialized()) if (ConfigBuilderPlugin.getPlugin().getActivePump().isSuspended() || !ConfigBuilderPlugin.getPlugin().getActivePump().isInitialized())
@ -891,10 +883,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
getContext().startActivity(intent); getContext().startActivity(intent);
return true; return true;
} catch (ActivityNotFoundException e) { } catch (ActivityNotFoundException e) {
new AlertDialog.Builder(getContext()) OKDialog.show(getContext(), "", MainApp.gs(R.string.error_starting_cgm));
.setMessage(R.string.error_starting_cgm)
.setPositiveButton("OK", null)
.show();
return false; return false;
} }
} }
@ -920,16 +909,11 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
LoopPlugin.getPlugin().invoke("Accept temp button", false); LoopPlugin.getPlugin().invoke("Accept temp button", false);
final LoopPlugin.LastRun finalLastRun = LoopPlugin.lastRun; final LoopPlugin.LastRun finalLastRun = LoopPlugin.lastRun;
if (finalLastRun != null && finalLastRun.lastAPSRun != null && finalLastRun.constraintsProcessed.isChangeRequested()) { if (finalLastRun != null && finalLastRun.lastAPSRun != null && finalLastRun.constraintsProcessed.isChangeRequested()) {
AlertDialog.Builder builder = new AlertDialog.Builder(context); OKDialog.showConfirmation(context, MainApp.gs(R.string.pump_tempbasal_label), finalLastRun.constraintsProcessed.toSpanned(), () -> {
builder.setTitle(MainApp.gs(R.string.confirmation));
builder.setMessage(MainApp.gs(R.string.setbasalquestion) + "\n" + finalLastRun.constraintsProcessed);
builder.setPositiveButton(MainApp.gs(R.string.ok), (dialog, id) -> {
hideTempRecommendation(); hideTempRecommendation();
clearNotification(); clearNotification();
LoopPlugin.getPlugin().acceptChangeRequest(); LoopPlugin.getPlugin().acceptChangeRequest();
}); });
builder.setNegativeButton(MainApp.gs(R.string.cancel), null);
builder.show();
} }
} }
} }
@ -949,7 +933,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
Integer carbsAfterConstraints = MainApp.getConstraintChecker().applyCarbsConstraints(new Constraint<>(quickWizardEntry.carbs())).value(); Integer carbsAfterConstraints = MainApp.getConstraintChecker().applyCarbsConstraints(new Constraint<>(quickWizardEntry.carbs())).value();
if (Math.abs(wizard.getInsulinAfterConstraints() - wizard.getCalculatedTotalInsulin()) >= pump.getPumpDescription().pumpType.determineCorrectBolusStepSize(wizard.getInsulinAfterConstraints()) || !carbsAfterConstraints.equals(quickWizardEntry.carbs())) { if (Math.abs(wizard.getInsulinAfterConstraints() - wizard.getCalculatedTotalInsulin()) >= pump.getPumpDescription().pumpType.determineCorrectBolusStepSize(wizard.getInsulinAfterConstraints()) || !carbsAfterConstraints.equals(quickWizardEntry.carbs())) {
OKDialog.show(getContext(), MainApp.gs(R.string.treatmentdeliveryerror), MainApp.gs(R.string.constraints_violation) + "\n" + MainApp.gs(R.string.changeyourinput), null); OKDialog.show(getContext(), MainApp.gs(R.string.treatmentdeliveryerror), MainApp.gs(R.string.constraints_violation) + "\n" + MainApp.gs(R.string.changeyourinput));
return; return;
} }
@ -1178,7 +1162,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
if (activeTemp != null) { if (activeTemp != null) {
fullText += MainApp.gs(R.string.pump_tempbasal_label) + ": " + activeTemp.toStringFull(); fullText += MainApp.gs(R.string.pump_tempbasal_label) + ": " + activeTemp.toStringFull();
} }
OKDialog.show(getActivity(), MainApp.gs(R.string.basal), fullText, null); OKDialog.show(getActivity(), MainApp.gs(R.string.basal), fullText);
}); });
} else { } else {
@ -1214,7 +1198,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
} }
extendedBolusView.setText(extendedBolusText); extendedBolusView.setText(extendedBolusText);
if (Config.NSCLIENT) { if (Config.NSCLIENT) {
extendedBolusView.setOnClickListener(v -> OKDialog.show(getActivity(), MainApp.gs(R.string.extendedbolus), extendedBolus.toString(), null)); extendedBolusView.setOnClickListener(v -> OKDialog.show(getActivity(), MainApp.gs(R.string.extended_bolus), extendedBolus.toString()));
} }
if (extendedBolusText.equals("")) if (extendedBolusText.equals(""))
extendedBolusView.setVisibility(Config.NSCLIENT ? View.INVISIBLE : View.GONE); extendedBolusView.setVisibility(Config.NSCLIENT ? View.INVISIBLE : View.GONE);
@ -1308,7 +1292,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
String iobtext1 = DecimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob) + "U\n" String iobtext1 = DecimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob) + "U\n"
+ MainApp.gs(R.string.bolus) + ": " + DecimalFormatter.to2Decimal(bolusIob.iob) + "U\n" + MainApp.gs(R.string.bolus) + ": " + DecimalFormatter.to2Decimal(bolusIob.iob) + "U\n"
+ MainApp.gs(R.string.basal) + ": " + DecimalFormatter.to2Decimal(basalIob.basaliob) + "U\n"; + MainApp.gs(R.string.basal) + ": " + DecimalFormatter.to2Decimal(basalIob.basaliob) + "U\n";
OKDialog.show(getActivity(), MainApp.gs(R.string.iob), iobtext1, null); OKDialog.show(getActivity(), MainApp.gs(R.string.iob), iobtext1);
}); });
} else if (MainApp.sResources.getBoolean(R.bool.isTablet)) { } else if (MainApp.sResources.getBoolean(R.bool.isTablet)) {
String iobtext = DecimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob) + "U (" String iobtext = DecimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob) + "U ("
@ -1360,19 +1344,19 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
// pump status from ns // pump status from ns
if (pumpDeviceStatusView != null) { if (pumpDeviceStatusView != null) {
pumpDeviceStatusView.setText(NSDeviceStatus.getInstance().getPumpStatus()); pumpDeviceStatusView.setText(NSDeviceStatus.getInstance().getPumpStatus());
pumpDeviceStatusView.setOnClickListener(v -> OKDialog.show(getActivity(), MainApp.gs(R.string.pump), NSDeviceStatus.getInstance().getExtendedPumpStatus(), null)); pumpDeviceStatusView.setOnClickListener(v -> OKDialog.show(getActivity(), MainApp.gs(R.string.pump), NSDeviceStatus.getInstance().getExtendedPumpStatus()));
} }
// OpenAPS status from ns // OpenAPS status from ns
if (openapsDeviceStatusView != null) { if (openapsDeviceStatusView != null) {
openapsDeviceStatusView.setText(NSDeviceStatus.getInstance().getOpenApsStatus()); openapsDeviceStatusView.setText(NSDeviceStatus.getInstance().getOpenApsStatus());
openapsDeviceStatusView.setOnClickListener(v -> OKDialog.show(getActivity(), MainApp.gs(R.string.openaps), NSDeviceStatus.getInstance().getExtendedOpenApsStatus(), null)); openapsDeviceStatusView.setOnClickListener(v -> OKDialog.show(getActivity(), MainApp.gs(R.string.openaps), NSDeviceStatus.getInstance().getExtendedOpenApsStatus()));
} }
// Uploader status from ns // Uploader status from ns
if (uploaderDeviceStatusView != null) { if (uploaderDeviceStatusView != null) {
uploaderDeviceStatusView.setText(NSDeviceStatus.getInstance().getUploaderStatusSpanned()); uploaderDeviceStatusView.setText(NSDeviceStatus.getInstance().getUploaderStatusSpanned());
uploaderDeviceStatusView.setOnClickListener(v -> OKDialog.show(getActivity(), MainApp.gs(R.string.uploader), NSDeviceStatus.getInstance().getExtendedUploaderStatus(), null)); uploaderDeviceStatusView.setOnClickListener(v -> OKDialog.show(getActivity(), MainApp.gs(R.string.uploader), NSDeviceStatus.getInstance().getExtendedUploaderStatus()));
} }
// Sensitivity // Sensitivity

View file

@ -1,198 +0,0 @@
package info.nightscout.androidaps.plugins.general.overview.dialogs;
import android.app.Activity;
import android.os.Bundle;
import android.os.SystemClock;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.fragment.app.DialogFragment;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.events.EventPumpStatusChanged;
import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.plugins.bus.RxBus;
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.general.overview.events.EventDismissBolusProgressIfRunning;
import info.nightscout.androidaps.plugins.general.overview.events.EventOverviewBolusProgress;
import info.nightscout.androidaps.utils.FabricPrivacy;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
public class BolusProgressDialog extends DialogFragment implements View.OnClickListener {
private static Logger log = LoggerFactory.getLogger(L.UI);
private CompositeDisposable disposable = new CompositeDisposable();
Button stopButton;
TextView statusView;
TextView stopPressedView;
ProgressBar progressBar;
BolusProgressHelperActivity helperActivity;
static double amount;
public static boolean bolusEnded = false;
public static boolean running = true;
public static boolean stopPressed = false;
private String state;
private final static String DEFAULT_STATE = MainApp.gs(R.string.waitingforpump);
public BolusProgressDialog() {
super();
}
public void setInsulin(double amount) {
BolusProgressDialog.amount = amount;
bolusEnded = false;
}
public void setHelperActivity(BolusProgressHelperActivity activity) {
this.helperActivity = activity;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
getDialog().setTitle(String.format(MainApp.gs(R.string.overview_bolusprogress_goingtodeliver), amount));
View view = inflater.inflate(R.layout.overview_bolusprogress_dialog, container, false);
stopButton = view.findViewById(R.id.overview_bolusprogress_stop);
statusView = view.findViewById(R.id.overview_bolusprogress_status);
stopPressedView = view.findViewById(R.id.overview_bolusprogress_stoppressed);
progressBar = view.findViewById(R.id.overview_bolusprogress_progressbar);
stopButton.setOnClickListener(this);
progressBar.setMax(100);
state = savedInstanceState != null ? savedInstanceState.getString("state", DEFAULT_STATE) : DEFAULT_STATE;
statusView.setText(state);
setCancelable(false);
stopPressed = false;
return view;
}
@Override
public void onResume() {
super.onResume();
if (L.isEnabled(L.UI))
log.debug("onResume");
if (!ConfigBuilderPlugin.getPlugin().getCommandQueue().bolusInQueue()) {
bolusEnded = true;
}
if (bolusEnded) {
dismiss();
} else {
if (getDialog() != null)
getDialog().getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
running = true;
if (L.isEnabled(L.UI))
log.debug("onResume running");
}
disposable.add(RxBus.INSTANCE
.toObservable(EventPumpStatusChanged.class)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(event -> statusView.setText(event.getStatus()), FabricPrivacy::logException)
);
disposable.add(RxBus.INSTANCE
.toObservable(EventDismissBolusProgressIfRunning.class)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(event -> {
if (L.isEnabled(L.UI)) log.debug("EventDismissBolusProgressIfRunning");
if (BolusProgressDialog.running) dismiss();
}, FabricPrivacy::logException)
);
disposable.add(RxBus.INSTANCE
.toObservable(EventOverviewBolusProgress.class)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(event -> {
if (L.isEnabled(L.UI))
log.debug("Status: " + event.getStatus() + " Percent: " + event.getPercent());
statusView.setText(event.getStatus());
progressBar.setProgress(event.getPercent());
if (event.getPercent() == 100) {
stopButton.setVisibility(View.INVISIBLE);
scheduleDismiss();
}
state = event.getStatus();
}, FabricPrivacy::logException)
);
}
@Override
public void dismiss() {
if (L.isEnabled(L.UI))
log.debug("dismiss");
try {
super.dismiss();
} catch (IllegalStateException e) {
// dialog not running yet. onResume will try again. Set bolusEnded to make extra
// sure onResume will catch this
bolusEnded = true;
log.error("Unhandled exception", e);
}
if (helperActivity != null) {
helperActivity.finish();
}
}
@Override
public void onPause() {
if (L.isEnabled(L.UI))
log.debug("onPause");
running = false;
super.onPause();
disposable.clear();
}
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
outState.putString("state", state);
log.debug("storing state: " + state);
super.onSaveInstanceState(outState);
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.overview_bolusprogress_stop:
if (L.isEnabled(L.UI))
log.debug("Stop bolus delivery button pressed");
stopPressed = true;
stopPressedView.setVisibility(View.VISIBLE);
stopButton.setVisibility(View.INVISIBLE);
ConfigBuilderPlugin.getPlugin().getCommandQueue().cancelAllBoluses();
break;
}
}
private void scheduleDismiss() {
if (L.isEnabled(L.UI))
log.debug("scheduleDismiss");
Thread t = new Thread(() -> {
SystemClock.sleep(5000);
BolusProgressDialog.bolusEnded = true;
Activity activity = getActivity();
if (activity != null) {
activity.runOnUiThread(() -> {
try {
if (running) {
if (L.isEnabled(L.UI))
log.debug("executing");
dismiss();
}
} catch (Exception e) {
log.error("Unhandled exception", e);
}
});
}
});
t.start();
}
}

View file

@ -1,20 +0,0 @@
package info.nightscout.androidaps.plugins.general.overview.dialogs;
import android.os.Bundle;
import info.nightscout.androidaps.activities.NoSplashAppCompatActivity;
public class BolusProgressHelperActivity extends NoSplashAppCompatActivity {
public BolusProgressHelperActivity() {
super();
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
BolusProgressDialog bolusProgressDialog = new BolusProgressDialog();
bolusProgressDialog.setHelperActivity(this);
bolusProgressDialog.setInsulin(getIntent().getDoubleExtra("insulin", 0d));
bolusProgressDialog.show(getSupportFragmentManager(), "BolusProgress");
}
}

View file

@ -1,94 +0,0 @@
package info.nightscout.androidaps.plugins.general.overview.dialogs;
import android.content.Context;
import android.os.Bundle;
import androidx.fragment.app.DialogFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.TextView;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.text.DecimalFormat;
import info.nightscout.androidaps.Constants;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
import info.nightscout.androidaps.utils.NumberPicker;
import info.nightscout.androidaps.utils.SafeParse;
import info.nightscout.androidaps.utils.XdripCalibrations;
public class CalibrationDialog extends DialogFragment implements View.OnClickListener {
private static Logger log = LoggerFactory.getLogger(CalibrationDialog.class);
NumberPicker bgNumber;
TextView unitsView;
Context context;
public CalibrationDialog() {
// Required empty public constructor
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
this.context = context;
}
@Override
public void onDetach() {
super.onDetach();
this.context = null;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.overview_calibration_dialog, container, false);
getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
view.findViewById(R.id.ok).setOnClickListener(this);
view.findViewById(R.id.cancel).setOnClickListener(this);
String units = ProfileFunctions.getSystemUnits();
Double bg = Profile.fromMgdlToUnits(GlucoseStatus.getGlucoseStatusData() != null ? GlucoseStatus.getGlucoseStatusData().glucose : 0d, units);
bgNumber = (NumberPicker) view.findViewById(R.id.overview_calibration_bg);
if (units.equals(Constants.MMOL))
bgNumber.setParams(bg, 0d, 30d, 0.1d, new DecimalFormat("0.0"), false, view.findViewById(R.id.ok));
else
bgNumber.setParams(bg, 0d, 500d, 1d, new DecimalFormat("0"), false, view.findViewById(R.id.ok));
unitsView = (TextView) view.findViewById(R.id.overview_calibration_units);
unitsView.setText(units);
setCancelable(true);
getDialog().setCanceledOnTouchOutside(false);
return view;
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.ok:
final Double bg = SafeParse.stringToDouble(bgNumber.getText());
XdripCalibrations.confirmAndSendCalibration(bg, context);
dismiss();
break;
case R.id.cancel:
dismiss();
break;
}
}
}

View file

@ -1,443 +0,0 @@
package info.nightscout.androidaps.plugins.general.overview.dialogs;
import android.os.Bundle;
import androidx.fragment.app.DialogFragment;
import androidx.appcompat.app.AlertDialog;
import android.text.Editable;
import android.text.Html;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.RadioButton;
import com.google.common.base.Joiner;
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.text.DecimalFormat;
import java.util.LinkedList;
import java.util.List;
import info.nightscout.androidaps.Constants;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.db.BgReading;
import info.nightscout.androidaps.db.CareportalEvent;
import info.nightscout.androidaps.db.DatabaseHelper;
import info.nightscout.androidaps.db.Source;
import info.nightscout.androidaps.db.TempTarget;
import info.nightscout.androidaps.interfaces.Constraint;
import info.nightscout.androidaps.plugins.treatments.CarbsGenerator;
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
import info.nightscout.androidaps.utils.DateUtil;
import info.nightscout.androidaps.utils.DecimalFormatter;
import info.nightscout.androidaps.utils.DefaultValueHelper;
import info.nightscout.androidaps.utils.NumberPicker;
import info.nightscout.androidaps.utils.SP;
import info.nightscout.androidaps.utils.ToastUtils;
import static info.nightscout.androidaps.utils.DateUtil.now;
public class NewCarbsDialog extends DialogFragment implements OnClickListener, CompoundButton.OnCheckedChangeListener {
private static Logger log = LoggerFactory.getLogger(NewCarbsDialog.class);
private static final int FAV1_DEFAULT = 5;
private static final int FAV2_DEFAULT = 10;
private static final int FAV3_DEFAULT = 20;
private RadioButton startActivityTTCheckbox;
private RadioButton startEatingSoonTTCheckbox;
private RadioButton startHypoTTCheckbox;
private boolean togglingTT;
private NumberPicker editTime;
private NumberPicker editDuration;
private NumberPicker editCarbs;
private Integer maxCarbs;
private EditText notesEdit;
//one shot guards
private boolean accepted;
private boolean okClicked;
public NewCarbsDialog() {
}
final private TextWatcher textWatcher = new TextWatcher() {
@Override
public void afterTextChanged(Editable s) {
validateInputs();
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
};
private void validateInputs() {
int time = editTime.getValue().intValue();
if (time > 12 * 60 || time < -12 * 60) {
editTime.setValue(0d);
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.constraintapllied));
}
Double duration = editDuration.getValue();
if (duration > 10) {
editDuration.setValue(0d);
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.constraintapllied));
}
int carbs = editCarbs.getValue().intValue();
if (carbs > maxCarbs) {
editCarbs.setValue(0d);
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.carbsconstraintapplied));
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.overview_newcarbs_dialog, container, false);
view.findViewById(R.id.ok).setOnClickListener(this);
view.findViewById(R.id.cancel).setOnClickListener(this);
getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
startActivityTTCheckbox = view.findViewById(R.id.newcarbs_activity_tt);
startActivityTTCheckbox.setOnCheckedChangeListener(this);
startEatingSoonTTCheckbox = view.findViewById(R.id.newcarbs_eating_soon_tt);
startEatingSoonTTCheckbox.setOnCheckedChangeListener(this);
startHypoTTCheckbox = view.findViewById(R.id.newcarbs_hypo_tt);
editTime = view.findViewById(R.id.newcarbs_time);
editTime.setParams(0d, -12 * 60d, 12 * 60d, 5d, new DecimalFormat("0"), false, view.findViewById(R.id.ok), textWatcher);
editDuration = view.findViewById(R.id.new_carbs_duration);
editDuration.setParams(0d, 0d, 10d, 1d, new DecimalFormat("0"), false, view.findViewById(R.id.ok), textWatcher);
maxCarbs = MainApp.getConstraintChecker().getMaxCarbsAllowed().value();
editCarbs = view.findViewById(R.id.newcarb_carbsamount);
editCarbs.setParams(0d, 0d, (double) maxCarbs, 1d, new DecimalFormat("0"), false, view.findViewById(R.id.ok), textWatcher);
Button fav1Button = view.findViewById(R.id.newcarbs_plus1);
fav1Button.setOnClickListener(this);
fav1Button.setText(toSignedString(SP.getInt(R.string.key_carbs_button_increment_1, FAV1_DEFAULT)));
Button fav2Button = view.findViewById(R.id.newcarbs_plus2);
fav2Button.setOnClickListener(this);
fav2Button.setText(toSignedString(SP.getInt(R.string.key_carbs_button_increment_2, FAV2_DEFAULT)));
Button fav3Button = view.findViewById(R.id.newcarbs_plus3);
fav3Button.setOnClickListener(this);
fav3Button.setText(toSignedString(SP.getInt(R.string.key_carbs_button_increment_3, FAV3_DEFAULT)));
LinearLayout notesLayout = view.findViewById(R.id.newcarbs_notes_layout);
notesLayout.setVisibility(SP.getBoolean(R.string.key_show_notes_entry_dialogs, false) ? View.VISIBLE : View.GONE);
notesEdit = view.findViewById(R.id.newcarbs_notes);
BgReading bgReading = DatabaseHelper.actualBg();
if (bgReading != null && bgReading.value < 72) {
startHypoTTCheckbox.setChecked(true);
// see #onCheckedChanged why listeners are registered like this
startHypoTTCheckbox.setOnClickListener(this);
} else {
startHypoTTCheckbox.setOnCheckedChangeListener(this);
}
setCancelable(true);
getDialog().setCanceledOnTouchOutside(false);
//recovering state if there is something
if (savedInstanceState != null) {
editCarbs.setValue(savedInstanceState.getDouble("editCarbs"));
editTime.setValue(savedInstanceState.getDouble("editTime"));
editDuration.setValue(savedInstanceState.getDouble("editDuration"));
}
return view;
}
private String toSignedString(int value) {
return value > 0 ? "+" + value : String.valueOf(value);
}
@Override
public void onSaveInstanceState(Bundle carbsDialogState) {
carbsDialogState.putBoolean("startActivityTTCheckbox",startActivityTTCheckbox.isChecked());
carbsDialogState.putBoolean("startEatingSoonTTCheckbox", startEatingSoonTTCheckbox.isChecked());
carbsDialogState.putBoolean("startHypoTTCheckbox", startHypoTTCheckbox.isChecked());
carbsDialogState.putDouble("editTime", editTime.getValue());
carbsDialogState.putDouble("editDuration", editDuration.getValue());
carbsDialogState.putDouble("editCarbs", editCarbs.getValue());
super.onSaveInstanceState(carbsDialogState);
}
@Override
public synchronized void onClick(View view) {
switch (view.getId()) {
case R.id.ok:
submit();
break;
case R.id.cancel:
dismiss();
break;
case R.id.newcarbs_plus1:
editCarbs.setValue(Math.max(0, editCarbs.getValue()
+ SP.getInt(R.string.key_carbs_button_increment_1, FAV1_DEFAULT)));
validateInputs();
break;
case R.id.newcarbs_plus2:
editCarbs.setValue(Math.max(0, editCarbs.getValue()
+ SP.getInt(R.string.key_carbs_button_increment_2, FAV2_DEFAULT)));
validateInputs();
break;
case R.id.newcarbs_plus3:
editCarbs.setValue(Math.max(0, editCarbs.getValue()
+ SP.getInt(R.string.key_carbs_button_increment_3, FAV3_DEFAULT)));
validateInputs();
break;
case R.id.newcarbs_activity_tt:
if (togglingTT) {
togglingTT = false;
break;
}
startActivityTTCheckbox.setOnClickListener(null);
startActivityTTCheckbox.setOnCheckedChangeListener(null);
startActivityTTCheckbox.setChecked(false);
startActivityTTCheckbox.setOnCheckedChangeListener(this);
break;
case R.id.newcarbs_eating_soon_tt:
if (togglingTT) {
togglingTT = false;
break;
}
startEatingSoonTTCheckbox.setOnClickListener(null);
startEatingSoonTTCheckbox.setOnCheckedChangeListener(null);
startEatingSoonTTCheckbox.setChecked(false);
startEatingSoonTTCheckbox.setOnCheckedChangeListener(this);
break;
case R.id.newcarbs_hypo_tt:
if (togglingTT) {
togglingTT = false;
break;
}
startHypoTTCheckbox.setOnClickListener(null);
startHypoTTCheckbox.setOnCheckedChangeListener(null);
startHypoTTCheckbox.setChecked(false);
startHypoTTCheckbox.setOnCheckedChangeListener(this);
break;
}
}
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
// Logic to disable a selected radio when pressed: when a checked radio
// is pressed, no CheckChanged event is triggered, so register a Click event
// when checking a radio. Since Click events come after CheckChanged events,
// the Click event is triggered immediately after this. Thus, set togglingTT
// var to true, so that the first Click event fired after this is ignored.
// Radios remove themselves from Click events once unchecked.
// Since radios are not in a group, their state is manually updated here.
switch (buttonView.getId()) {
case R.id.newcarbs_activity_tt:
togglingTT = true;
startActivityTTCheckbox.setOnClickListener(this);
startEatingSoonTTCheckbox.setOnCheckedChangeListener(null);
startEatingSoonTTCheckbox.setChecked(false);
startEatingSoonTTCheckbox.setOnCheckedChangeListener(this);
startHypoTTCheckbox.setOnCheckedChangeListener(null);
startHypoTTCheckbox.setChecked(false);
startHypoTTCheckbox.setOnCheckedChangeListener(this);
break;
case R.id.newcarbs_eating_soon_tt:
togglingTT = true;
startEatingSoonTTCheckbox.setOnClickListener(this);
startActivityTTCheckbox.setOnCheckedChangeListener(null);
startActivityTTCheckbox.setChecked(false);
startActivityTTCheckbox.setOnCheckedChangeListener(this);
startHypoTTCheckbox.setOnCheckedChangeListener(null);
startHypoTTCheckbox.setChecked(false);
startHypoTTCheckbox.setOnCheckedChangeListener(this);
break;
case R.id.newcarbs_hypo_tt:
togglingTT = true;
startHypoTTCheckbox.setOnClickListener(this);
startActivityTTCheckbox.setOnCheckedChangeListener(null);
startActivityTTCheckbox.setChecked(false);
startActivityTTCheckbox.setOnCheckedChangeListener(this);
startEatingSoonTTCheckbox.setOnCheckedChangeListener(null);
startEatingSoonTTCheckbox.setChecked(false);
startEatingSoonTTCheckbox.setOnCheckedChangeListener(this);
break;
}
}
private void submit() {
if (okClicked) {
log.debug("guarding: ok already clicked");
dismiss();
return;
}
okClicked = true;
try {
final Profile currentProfile = ProfileFunctions.getInstance().getProfile();
if (currentProfile == null) {
return;
}
int carbs = editCarbs.getValue().intValue();
Integer carbsAfterConstraints = MainApp.getConstraintChecker().applyCarbsConstraints(new Constraint<>(carbs)).value();
final String units = ProfileFunctions.getSystemUnits();
DefaultValueHelper helper = new DefaultValueHelper();
int activityTTDuration = helper.determineActivityTTDuration();
double activityTT = helper.determineActivityTT();
int eatingSoonTTDuration = helper.determineEatingSoonTTDuration();
double eatingSoonTT = helper.determineEatingSoonTT();
int hypoTTDuration = helper.determineHypoTTDuration();
double hypoTT = helper.determineHypoTT();
List<String> actions = new LinkedList<>();
if (startActivityTTCheckbox.isChecked()) {
String unitLabel = "mg/dl";
if (units.equals(Constants.MMOL)) {
unitLabel = "mmol/l";
}
actions.add(MainApp.gs(R.string.temptargetshort) + ": " + "<font color='" + MainApp.gc(R.color.tempTargetConfirmation) + "'>" + DecimalFormatter.to1Decimal(activityTT) + " " + unitLabel + " (" + activityTTDuration + " min)</font>");
}
if (startEatingSoonTTCheckbox.isChecked()) {
if (units.equals(Constants.MMOL)) {
actions.add(MainApp.gs(R.string.temptargetshort) + ": " + "<font color='" + MainApp.gc(R.color.tempTargetConfirmation) + "'>" + DecimalFormatter.to1Decimal(eatingSoonTT) + " mmol/l (" + eatingSoonTTDuration + " min)</font>");
} else {
actions.add(MainApp.gs(R.string.temptargetshort) + ": " + "<font color='" + MainApp.gc(R.color.tempTargetConfirmation) + "'>" + DecimalFormatter.to0Decimal(eatingSoonTT) + " mg/dl (" + eatingSoonTTDuration + " min)</font>");
}
}
if (startHypoTTCheckbox.isChecked()) {
if (units.equals(Constants.MMOL)) {
actions.add(MainApp.gs(R.string.temptargetshort) + ": " + "<font color='" + MainApp.gc(R.color.tempTargetConfirmation) + "'>" + DecimalFormatter.to1Decimal(hypoTT) + " mmol/l (" + hypoTTDuration + " min)</font>");
} else {
actions.add(MainApp.gs(R.string.temptargetshort) + ": " + "<font color='" + MainApp.gc(R.color.tempTargetConfirmation) + "'>" + DecimalFormatter.to0Decimal(hypoTT) + " mg/dl (" + hypoTTDuration + " min)</font>");
}
}
int timeOffset = editTime.getValue().intValue();
final long time = now() + timeOffset * 1000 * 60;
if (timeOffset != 0) {
actions.add(MainApp.gs(R.string.time) + ": " + DateUtil.dateAndTimeString(time));
}
int duration = editDuration.getValue().intValue();
if (duration > 0) {
actions.add(MainApp.gs(R.string.duration) + ": " + duration + MainApp.gs(R.string.shorthour));
}
if (carbs > 0) {
actions.add(MainApp.gs(R.string.carbs) + ": " + "<font color='" + MainApp.gc(R.color.carbs) + "'>" + carbsAfterConstraints + "g" + "</font>");
}
if (!carbsAfterConstraints.equals(carbs)) {
actions.add("<font color='" + MainApp.gc(R.color.warning) + "'>" + MainApp.gs(R.string.carbsconstraintapplied) + "</font>");
}
final String notes = notesEdit.getText().toString();
if (!notes.isEmpty()) {
actions.add(MainApp.gs(R.string.careportal_newnstreatment_notes_label) + ": " + notes);
}
final double finalActivityTT = activityTT;
final int finalActivityTTDuration = activityTTDuration;
final double finalEatigSoonTT = eatingSoonTT;
final int finalEatingSoonTTDuration = eatingSoonTTDuration;
final double finalHypoTT = hypoTT;
final int finalHypoTTDuration = hypoTTDuration;
final AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setTitle(MainApp.gs(R.string.confirmation));
if (carbsAfterConstraints > 0 || startActivityTTCheckbox.isChecked()
|| startEatingSoonTTCheckbox.isChecked() || startHypoTTCheckbox.isChecked()) {
builder.setMessage(Html.fromHtml(Joiner.on("<br/>").join(actions)));
builder.setPositiveButton(MainApp.gs(R.string.ok), (dialog, id) -> {
synchronized (builder) {
if (accepted) {
log.debug("guarding: already accepted");
return;
}
accepted = true;
if (startActivityTTCheckbox.isChecked()) {
TempTarget tempTarget = new TempTarget()
.date(System.currentTimeMillis())
.duration(finalActivityTTDuration)
.reason(MainApp.gs(R.string.activity))
.source(Source.USER)
.low(Profile.toMgdl(finalActivityTT, ProfileFunctions.getSystemUnits()))
.high(Profile.toMgdl(finalActivityTT, ProfileFunctions.getSystemUnits()));
TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget);
} else if (startEatingSoonTTCheckbox.isChecked()) {
TempTarget tempTarget = new TempTarget()
.date(System.currentTimeMillis())
.duration(finalEatingSoonTTDuration)
.reason(MainApp.gs(R.string.eatingsoon))
.source(Source.USER)
.low(Profile.toMgdl(finalEatigSoonTT, ProfileFunctions.getSystemUnits()))
.high(Profile.toMgdl(finalEatigSoonTT, ProfileFunctions.getSystemUnits()));
TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget);
} else if (startHypoTTCheckbox.isChecked()) {
TempTarget tempTarget = new TempTarget()
.date(System.currentTimeMillis())
.duration(finalHypoTTDuration)
.reason(MainApp.gs(R.string.hypo))
.source(Source.USER)
.low(Profile.toMgdl(finalHypoTT, ProfileFunctions.getSystemUnits()))
.high(Profile.toMgdl(finalHypoTT, ProfileFunctions.getSystemUnits()));
TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget);
}
if (carbsAfterConstraints > 0) {
if (duration == 0) {
CarbsGenerator.createCarb(carbsAfterConstraints, time, CareportalEvent.CARBCORRECTION, notes);
} else {
CarbsGenerator.generateCarbs(carbsAfterConstraints, time, duration, notes);
NSUpload.uploadEvent(CareportalEvent.NOTE, now() - 2000, MainApp.gs(R.string.generated_ecarbs_note, carbsAfterConstraints, duration, timeOffset));
}
}
}
});
} else {
builder.setMessage(MainApp.gs(R.string.no_action_selected));
}
builder.setNegativeButton(MainApp.gs(R.string.cancel), null);
builder.show();
dismiss();
} catch (Exception e) {
log.error("Unhandled exception", e);
}
}
}

View file

@ -1,317 +0,0 @@
package info.nightscout.androidaps.plugins.general.overview.dialogs;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import androidx.fragment.app.DialogFragment;
import androidx.appcompat.app.AlertDialog;
import android.text.Editable;
import android.text.Html;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.LinearLayout;
import com.google.common.base.Joiner;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.text.DecimalFormat;
import java.util.LinkedList;
import java.util.List;
import info.nightscout.androidaps.Constants;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.DetailedBolusInfo;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.db.CareportalEvent;
import info.nightscout.androidaps.db.Source;
import info.nightscout.androidaps.db.TempTarget;
import info.nightscout.androidaps.interfaces.Constraint;
import info.nightscout.androidaps.interfaces.PumpInterface;
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
import info.nightscout.androidaps.queue.Callback;
import info.nightscout.androidaps.utils.DateUtil;
import info.nightscout.androidaps.utils.DecimalFormatter;
import info.nightscout.androidaps.utils.NumberPicker;
import info.nightscout.androidaps.utils.SP;
import info.nightscout.androidaps.utils.SafeParse;
import info.nightscout.androidaps.utils.T;
import info.nightscout.androidaps.utils.ToastUtils;
import static info.nightscout.androidaps.utils.DateUtil.now;
public class NewInsulinDialog extends DialogFragment implements OnClickListener {
private static Logger log = LoggerFactory.getLogger(NewInsulinDialog.class);
private static final double PLUS1_DEFAULT = 0.5d;
private static final double PLUS2_DEFAULT = 1d;
private static final double PLUS3_DEFAULT = 2d;
private CheckBox startEatingSoonTTCheckbox;
private CheckBox recordOnlyCheckbox;
private LinearLayout editLayout;
private NumberPicker editTime;
private NumberPicker editInsulin;
private Double maxInsulin;
private EditText notesEdit;
//one shot guards
private boolean accepted;
private boolean okClicked;
public NewInsulinDialog() {
}
final private TextWatcher textWatcher = new TextWatcher() {
@Override
public void afterTextChanged(Editable s) {
validateInputs();
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
};
private void validateInputs() {
int time = editTime.getValue().intValue();
if (Math.abs(time) > 12 * 60) {
editTime.setValue(0d);
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.constraintapllied));
}
Double insulin = editInsulin.getValue();
if (insulin > maxInsulin) {
editInsulin.setValue(0d);
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.bolusconstraintapplied));
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.overview_newinsulin_dialog, container, false);
view.findViewById(R.id.ok).setOnClickListener(this);
view.findViewById(R.id.cancel).setOnClickListener(this);
getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
startEatingSoonTTCheckbox = view.findViewById(R.id.newinsulin_start_eating_soon_tt);
recordOnlyCheckbox = view.findViewById(R.id.newinsulin_record_only);
recordOnlyCheckbox.setOnCheckedChangeListener((buttonView, isChecked) -> editLayout.setVisibility(isChecked ? View.VISIBLE : View.GONE));
editLayout = view.findViewById(R.id.newinsulin_time_layout);
editLayout.setVisibility(View.GONE);
editTime = view.findViewById(R.id.newinsulin_time);
editTime.setParams(0d, -12 * 60d, 12 * 60d, 5d, new DecimalFormat("0"), false, view.findViewById(R.id.ok), textWatcher);
maxInsulin = MainApp.getConstraintChecker().getMaxBolusAllowed().value();
editInsulin = view.findViewById(R.id.newinsulin_amount);
editInsulin.setParams(0d, 0d, maxInsulin, ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription().bolusStep, DecimalFormatter.pumpSupportedBolusFormat(), false, view.findViewById(R.id.ok), textWatcher);
Button plus1Button = view.findViewById(R.id.newinsulin_plus05);
plus1Button.setOnClickListener(this);
plus1Button.setText(toSignedString(SP.getDouble(MainApp.gs(R.string.key_insulin_button_increment_1), PLUS1_DEFAULT)));
Button plus2Button = view.findViewById(R.id.newinsulin_plus10);
plus2Button.setOnClickListener(this);
plus2Button.setText(toSignedString(SP.getDouble(MainApp.gs(R.string.key_insulin_button_increment_2), PLUS2_DEFAULT)));
Button plus3Button = view.findViewById(R.id.newinsulin_plus20);
plus3Button.setOnClickListener(this);
plus3Button.setText(toSignedString(SP.getDouble(MainApp.gs(R.string.key_insulin_button_increment_3), PLUS3_DEFAULT)));
LinearLayout notesLayout = view.findViewById(R.id.newinsulin_notes_layout);
notesLayout.setVisibility(SP.getBoolean(R.string.key_show_notes_entry_dialogs, false) ? View.VISIBLE : View.GONE);
notesEdit = view.findViewById(R.id.newinsulin_notes);
setCancelable(true);
getDialog().setCanceledOnTouchOutside(false);
if (savedInstanceState != null) {
// log.debug("savedInstanceState in onCreate is:" + savedInstanceState.toString());
editInsulin.setValue(savedInstanceState.getDouble("editInsulin"));
editTime.setValue(savedInstanceState.getDouble("editTime"));
}
return view;
}
private String toSignedString(double value) {
String formatted = DecimalFormatter.toPumpSupportedBolus(value);
return value > 0 ? "+" + formatted : formatted;
}
@Override
public void onSaveInstanceState(Bundle insulinDialogState) {
insulinDialogState.putBoolean("startEatingSoonTTCheckbox", startEatingSoonTTCheckbox.isChecked());
insulinDialogState.putBoolean("recordOnlyCheckbox", recordOnlyCheckbox.isChecked());
insulinDialogState.putDouble("editTime", editTime.getValue());
insulinDialogState.putDouble("editInsulin", editInsulin.getValue());
insulinDialogState.putString("notesEdit", notesEdit.getText().toString());
log.debug("Instance state saved:" + insulinDialogState.toString());
super.onSaveInstanceState(insulinDialogState);
}
@Override
public synchronized void onClick(View view) {
switch (view.getId()) {
case R.id.ok:
submit();
break;
case R.id.cancel:
dismiss();
break;
case R.id.newinsulin_plus05:
editInsulin.setValue(Math.max(0, editInsulin.getValue()
+ SP.getDouble(MainApp.gs(R.string.key_insulin_button_increment_1), PLUS1_DEFAULT)));
validateInputs();
break;
case R.id.newinsulin_plus10:
editInsulin.setValue(Math.max(0, editInsulin.getValue()
+ SP.getDouble(MainApp.gs(R.string.key_insulin_button_increment_2), PLUS2_DEFAULT)));
validateInputs();
break;
case R.id.newinsulin_plus20:
editInsulin.setValue(Math.max(0, editInsulin.getValue()
+ SP.getDouble(MainApp.gs(R.string.key_insulin_button_increment_3), PLUS3_DEFAULT)));
validateInputs();
break;
}
}
private void submit() {
if (okClicked) {
log.debug("guarding: ok already clicked");
dismiss();
return;
}
okClicked = true;
try {
final PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
if (pump == null)
return;
Double insulin = SafeParse.stringToDouble(editInsulin.getText());
Double insulinAfterConstraints = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(insulin)).value();
List<String> actions = new LinkedList<>();
if (insulin > 0) {
actions.add(MainApp.gs(R.string.bolus) + ": " + "<font color='" + MainApp.gc(R.color.bolus) + "'>" + DecimalFormatter.toPumpSupportedBolus(insulinAfterConstraints) + "U" + "</font>");
if (recordOnlyCheckbox.isChecked()) {
actions.add("<font color='" + MainApp.gc(R.color.warning) + "'>" + MainApp.gs(R.string.bolusrecordedonly) + "</font>");
}
}
if (Math.abs(insulinAfterConstraints - insulin) > pump.getPumpDescription().pumpType.determineCorrectBolusStepSize(insulinAfterConstraints))
actions.add(MainApp.gs(R.string.bolusconstraintappliedwarning, MainApp.gc(R.color.warning), insulin, insulinAfterConstraints));
int eatingSoonTTDuration = SP.getInt(R.string.key_eatingsoon_duration, Constants.defaultEatingSoonTTDuration);
eatingSoonTTDuration = eatingSoonTTDuration > 0 ? eatingSoonTTDuration : Constants.defaultEatingSoonTTDuration;
double eatingSoonTT = SP.getDouble(R.string.key_eatingsoon_target, ProfileFunctions.getSystemUnits().equals(Constants.MMOL) ? Constants.defaultEatingSoonTTmmol : Constants.defaultEatingSoonTTmgdl);
eatingSoonTT = eatingSoonTT > 0 ? eatingSoonTT : ProfileFunctions.getSystemUnits().equals(Constants.MMOL) ? Constants.defaultEatingSoonTTmmol : Constants.defaultEatingSoonTTmgdl;
if (startEatingSoonTTCheckbox.isChecked()) {
if (ProfileFunctions.getSystemUnits().equals(Constants.MMOL)) {
actions.add(MainApp.gs(R.string.temptargetshort) + ": " + "<font color='" + MainApp.gc(R.color.tempTargetConfirmation) + "'>" + DecimalFormatter.to1Decimal(eatingSoonTT) + " mmol/l (" + eatingSoonTTDuration + " min)</font>");
} else
actions.add(MainApp.gs(R.string.temptargetshort) + ": " + "<font color='" + MainApp.gc(R.color.tempTargetConfirmation) + "'>" + DecimalFormatter.to0Decimal(eatingSoonTT) + " mg/dl (" + eatingSoonTTDuration + " min)</font>");
}
int timeOffset = editTime.getValue().intValue();
final long time = now() + T.mins(timeOffset).msecs();
if (timeOffset != 0) {
actions.add(MainApp.gs(R.string.time) + ": " + DateUtil.dateAndTimeString(time));
}
final String notes = notesEdit.getText().toString();
if (!notes.isEmpty()) {
actions.add(MainApp.gs(R.string.careportal_newnstreatment_notes_label) + ": " + notes);
}
final double finalInsulinAfterConstraints = insulinAfterConstraints;
final double finalEatigSoonTT = eatingSoonTT;
final int finalEatingSoonTTDuration = eatingSoonTTDuration;
final Context context = getContext();
final AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(MainApp.gs(R.string.confirmation));
if (finalInsulinAfterConstraints > 0 || startEatingSoonTTCheckbox.isChecked()) {
builder.setMessage(Html.fromHtml(Joiner.on("<br/>").join(actions)));
builder.setPositiveButton(MainApp.gs(R.string.ok), (dialog, id) -> {
synchronized (builder) {
if (accepted) {
log.debug("guarding: already accepted");
return;
}
accepted = true;
if (startEatingSoonTTCheckbox.isChecked()) {
TempTarget tempTarget = new TempTarget()
.date(System.currentTimeMillis())
.duration(finalEatingSoonTTDuration)
.reason(MainApp.gs(R.string.eatingsoon))
.source(Source.USER)
.low(Profile.toMgdl(finalEatigSoonTT, ProfileFunctions.getSystemUnits()))
.high(Profile.toMgdl(finalEatigSoonTT, ProfileFunctions.getSystemUnits()));
TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget);
}
if (finalInsulinAfterConstraints > 0) {
DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo();
detailedBolusInfo.eventType = CareportalEvent.CORRECTIONBOLUS;
detailedBolusInfo.insulin = finalInsulinAfterConstraints;
detailedBolusInfo.context = context;
detailedBolusInfo.source = Source.USER;
detailedBolusInfo.notes = notes;
if (recordOnlyCheckbox.isChecked()) {
detailedBolusInfo.date = time;
TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo, false);
} else {
detailedBolusInfo.date = now();
ConfigBuilderPlugin.getPlugin().getCommandQueue().bolus(detailedBolusInfo, new Callback() {
@Override
public void run() {
if (!result.success) {
Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class);
i.putExtra("soundid", R.raw.boluserror);
i.putExtra("status", result.comment);
i.putExtra("title", MainApp.gs(R.string.treatmentdeliveryerror));
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
MainApp.instance().startActivity(i);
}
}
});
}
}
}
});
} else {
builder.setMessage(MainApp.gs(R.string.no_action_selected));
}
builder.setNegativeButton(MainApp.gs(R.string.cancel), null);
builder.show();
dismiss();
} catch (Exception e) {
log.error("Unhandled exception", e);
}
}
}

View file

@ -1,213 +0,0 @@
package info.nightscout.androidaps.plugins.general.overview.dialogs;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import androidx.fragment.app.DialogFragment;
import androidx.appcompat.app.AlertDialog;
import android.text.Editable;
import android.text.Html;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.CheckBox;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.text.DecimalFormat;
import java.util.Objects;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.DetailedBolusInfo;
import info.nightscout.androidaps.db.CareportalEvent;
import info.nightscout.androidaps.db.Source;
import info.nightscout.androidaps.interfaces.Constraint;
import info.nightscout.androidaps.interfaces.PumpInterface;
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
import info.nightscout.androidaps.queue.Callback;
import info.nightscout.androidaps.utils.DecimalFormatter;
import info.nightscout.androidaps.utils.NumberPicker;
import info.nightscout.androidaps.utils.SafeParse;
import info.nightscout.androidaps.utils.ToastUtils;
public class NewTreatmentDialog extends DialogFragment implements OnClickListener {
private static Logger log = LoggerFactory.getLogger(NewTreatmentDialog.class);
private NumberPicker editCarbs;
private NumberPicker editInsulin;
private Integer maxCarbs;
private Double maxInsulin;
//one shot guards
private boolean accepted;
private boolean okClicked;
private CheckBox recordOnlyCheckbox;
public NewTreatmentDialog() {
}
final private TextWatcher textWatcher = new TextWatcher() {
@Override
public void afterTextChanged(Editable s) {
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
validateInputs();
}
};
private void validateInputs() {
Integer carbs = SafeParse.stringToInt(editCarbs.getText());
if (carbs > maxCarbs) {
editCarbs.setValue(0d);
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.carbsconstraintapplied));
}
Double insulin = SafeParse.stringToDouble(editInsulin.getText());
if (insulin > maxInsulin) {
editInsulin.setValue(0d);
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.bolusconstraintapplied));
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.overview_newtreatment_dialog, container, false);
view.findViewById(R.id.ok).setOnClickListener(this);
view.findViewById(R.id.cancel).setOnClickListener(this);
getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
maxCarbs = MainApp.getConstraintChecker().getMaxCarbsAllowed().value();
maxInsulin = MainApp.getConstraintChecker().getMaxBolusAllowed().value();
editCarbs = (NumberPicker) view.findViewById(R.id.treatments_newtreatment_carbsamount);
editInsulin = (NumberPicker) view.findViewById(R.id.treatments_newtreatment_insulinamount);
editCarbs.setParams(0d, 0d, (double) maxCarbs, 1d, new DecimalFormat("0"), false, view.findViewById(R.id.ok), textWatcher);
editInsulin.setParams(0d, 0d, maxInsulin, ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription().bolusStep, DecimalFormatter.pumpSupportedBolusFormat(), false, view.findViewById(R.id.ok), textWatcher);
recordOnlyCheckbox = (CheckBox) view.findViewById(R.id.newtreatment_record_only);
setCancelable(true);
getDialog().setCanceledOnTouchOutside(false);
return view;
}
@Override
public synchronized void onClick(View view) {
switch (view.getId()) {
case R.id.ok:
if (okClicked) {
log.debug("guarding: ok already clicked");
dismiss();
return;
}
okClicked = true;
try {
final PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
if (pump == null)
return;
Double insulin = SafeParse.stringToDouble(editInsulin.getText());
final Integer carbs = SafeParse.stringToInt(editCarbs.getText());
String confirmMessage = MainApp.gs(R.string.entertreatmentquestion) + "<br/>";
Double insulinAfterConstraints = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(insulin)).value();
Integer carbsAfterConstraints = MainApp.getConstraintChecker().applyCarbsConstraints(new Constraint<>(carbs)).value();
if (insulin > 0) {
confirmMessage += MainApp.gs(R.string.bolus) + ": " + "<font color='" + MainApp.gc(R.color.bolus) + "'>" + DecimalFormatter.toPumpSupportedBolus(insulinAfterConstraints) + "U" + "</font>";
if (recordOnlyCheckbox.isChecked()) {
confirmMessage += "<br/><font color='" + MainApp.gc(R.color.warning) + "'>" + MainApp.gs(R.string.bolusrecordedonly) + "</font>";
}
if (Math.abs(insulinAfterConstraints - insulin) > pump.getPumpDescription().pumpType.determineCorrectBolusStepSize(insulinAfterConstraints) || !Objects.equals(carbsAfterConstraints, carbs))
confirmMessage += "<br/>" + MainApp.gs(R.string.bolusconstraintappliedwarning, MainApp.gc(R.color.warning), insulin, insulinAfterConstraints);
}
if (carbsAfterConstraints > 0)
confirmMessage += "<br/>" + MainApp.gs(R.string.carbs) + ": " + "<font color='" + MainApp.gc(R.color.carbs) + "'>" + carbsAfterConstraints + "g" + "</font>";
final double finalInsulinAfterConstraints = insulinAfterConstraints;
final int finalCarbsAfterConstraints = carbsAfterConstraints;
final Context context = getContext();
final AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(MainApp.gs(R.string.confirmation));
builder.setMessage(Html.fromHtml(confirmMessage));
builder.setPositiveButton(MainApp.gs(R.string.ok), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
synchronized (builder) {
if (accepted) {
log.debug("guarding: already accepted");
return;
}
accepted = true;
if (finalInsulinAfterConstraints > 0 || finalCarbsAfterConstraints > 0) {
DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo();
if (finalInsulinAfterConstraints == 0)
detailedBolusInfo.eventType = CareportalEvent.CARBCORRECTION;
if (finalCarbsAfterConstraints == 0)
detailedBolusInfo.eventType = CareportalEvent.CORRECTIONBOLUS;
detailedBolusInfo.insulin = finalInsulinAfterConstraints;
detailedBolusInfo.carbs = finalCarbsAfterConstraints;
detailedBolusInfo.context = context;
detailedBolusInfo.source = Source.USER;
if (!(recordOnlyCheckbox.isChecked() && (detailedBolusInfo.insulin > 0 || ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription().storesCarbInfo))) {
ConfigBuilderPlugin.getPlugin().getCommandQueue().bolus(detailedBolusInfo, new Callback() {
@Override
public void run() {
if (!result.success) {
Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class);
i.putExtra("soundid", R.raw.boluserror);
i.putExtra("status", result.comment);
i.putExtra("title", MainApp.gs(R.string.treatmentdeliveryerror));
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
MainApp.instance().startActivity(i);
}
}
});
} else {
TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo, false);
}
}
}
}
});
builder.setNegativeButton(MainApp.gs(R.string.cancel), null);
builder.show();
dismiss();
} catch (Exception e) {
log.error("Unhandled exception", e);
}
break;
case R.id.cancel:
dismiss();
break;
}
}
}

View file

@ -21,7 +21,7 @@ import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R; import info.nightscout.androidaps.R;
import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.plugins.bus.RxBus; import info.nightscout.androidaps.plugins.bus.RxBus;
import info.nightscout.androidaps.plugins.general.nsclient.broadcasts.BroadcastAckAlarm; import info.nightscout.androidaps.plugins.general.nsclient.NSClientPlugin;
import info.nightscout.androidaps.plugins.general.overview.OverviewPlugin; import info.nightscout.androidaps.plugins.general.overview.OverviewPlugin;
import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification; import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification;
import info.nightscout.androidaps.utils.DateUtil; import info.nightscout.androidaps.utils.DateUtil;
@ -93,7 +93,7 @@ public class NotificationRecyclerViewAdapter extends RecyclerView.Adapter<Notifi
Notification notification = (Notification) v.getTag(); Notification notification = (Notification) v.getTag();
RxBus.INSTANCE.send(new EventDismissNotification(notification.id)); RxBus.INSTANCE.send(new EventDismissNotification(notification.id));
if (notification.nsAlarm != null) { if (notification.nsAlarm != null) {
BroadcastAckAlarm.handleClearAlarm(notification.nsAlarm, MainApp.instance().getApplicationContext(), 60 * 60 * 1000L); NSClientPlugin.getPlugin().handleClearAlarm(notification.nsAlarm, 60 * 60 * 1000L);
} }
// Adding current time to snooze if we got staleData // Adding current time to snooze if we got staleData
if (L.isEnabled(L.NOTIFICATION)) if (L.isEnabled(L.NOTIFICATION))

View file

@ -5,6 +5,7 @@ import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import dagger.android.support.DaggerFragment
import info.nightscout.androidaps.R import info.nightscout.androidaps.R
import info.nightscout.androidaps.plugins.bus.RxBus.toObservable import info.nightscout.androidaps.plugins.bus.RxBus.toObservable
import info.nightscout.androidaps.plugins.general.smsCommunicator.events.EventSmsCommunicatorUpdateGui import info.nightscout.androidaps.plugins.general.smsCommunicator.events.EventSmsCommunicatorUpdateGui
@ -15,11 +16,15 @@ import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable import io.reactivex.disposables.CompositeDisposable
import kotlinx.android.synthetic.main.smscommunicator_fragment.* import kotlinx.android.synthetic.main.smscommunicator_fragment.*
import java.util.* import java.util.*
import javax.inject.Inject
import kotlin.math.max import kotlin.math.max
class SmsCommunicatorFragment : Fragment() { class SmsCommunicatorFragment : DaggerFragment() {
private val disposable = CompositeDisposable() private val disposable = CompositeDisposable()
@Inject
lateinit var smsCommunicatorPlugin: SmsCommunicatorPlugin
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? { savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.smscommunicator_fragment, container, false) return inflater.inflate(R.layout.smscommunicator_fragment, container, false)
@ -47,12 +52,12 @@ class SmsCommunicatorFragment : Fragment() {
return (object1.date - object2.date).toInt() return (object1.date - object2.date).toInt()
} }
} }
Collections.sort(SmsCommunicatorPlugin.messages, CustomComparator()) Collections.sort(smsCommunicatorPlugin.messages, CustomComparator())
val messagesToShow = 40 val messagesToShow = 40
val start = max(0, SmsCommunicatorPlugin.messages.size - messagesToShow) val start = max(0, smsCommunicatorPlugin.messages.size - messagesToShow)
var logText = "" var logText = ""
for (x in start until SmsCommunicatorPlugin.messages.size) { for (x in start until smsCommunicatorPlugin.messages.size) {
val sms = SmsCommunicatorPlugin.messages[x] val sms = smsCommunicatorPlugin.messages[x]
when { when {
sms.ignored -> { sms.ignored -> {
logText += DateUtil.timeString(sms.date) + " &lt;&lt;&lt; " + "" + sms.phoneNumber + " <b>" + sms.text + "</b><br>" logText += DateUtil.timeString(sms.date) + " &lt;&lt;&lt; " + "" + sms.phoneNumber + " <b>" + sms.text + "</b><br>"

Some files were not shown because too many files have changed in this diff Show more