commit
8f7c4fe145
265 changed files with 8502 additions and 7269 deletions
137
.idea/codeStyles/Project.xml
Normal file
137
.idea/codeStyles/Project.xml
Normal 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>
|
5
.idea/codeStyles/codeStyleConfig.xml
Normal file
5
.idea/codeStyles/codeStyleConfig.xml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
<component name="ProjectCodeStyleConfiguration">
|
||||||
|
<state>
|
||||||
|
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
|
||||||
|
</state>
|
||||||
|
</component>
|
|
@ -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>
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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")
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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))
|
||||||
|
}
|
||||||
|
}
|
|
@ -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()
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()
|
||||||
|
|
||||||
|
@ -85,21 +81,21 @@ class SurveyActivity : NoSplashAppCompatActivity() {
|
||||||
|
|
||||||
val auth = FirebaseAuth.getInstance()
|
val auth = FirebaseAuth.getInstance()
|
||||||
auth.signInAnonymously()
|
auth.signInAnonymously()
|
||||||
.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)
|
||||||
} else {
|
} else {
|
||||||
log.error("signInAnonymously:failure", task.exception)
|
log.error("signInAnonymously:failure", task.exception)
|
||||||
ToastUtils.showToastInUiThread(this, "Authentication failed.")
|
ToastUtils.showToastInUiThread(this, "Authentication failed.")
|
||||||
//updateUI(null)
|
//updateUI(null)
|
||||||
}
|
|
||||||
|
|
||||||
// ...
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ...
|
||||||
|
}
|
||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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) {
|
JsonHelper.safeGetJSONObject(store, profileName, null)?.let { profileObject ->
|
||||||
val profileObject = store.getJSONObject(profileName)
|
// take units from profile and if N/A from store
|
||||||
if (profileObject != null && profileObject.has("units")) {
|
JsonHelper.safeGetStringAllowNull(profileObject, "units", JsonHelper.safeGetString(data, "units"))?.let { units ->
|
||||||
profile = Profile(profileObject, profileObject.getString("units"))
|
profile = Profile(profileObject, units)
|
||||||
cachedObjects[profileName] = profile
|
cachedObjects[profileName] = profile
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e: JSONException) {
|
|
||||||
log.error("Unhandled exception", e)
|
|
||||||
}
|
}
|
||||||
return profile
|
return profile
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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,36 +41,49 @@ 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 {
|
||||||
|
data.put("NSCLIENT_ID", nsClientID);
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
this.data = data.toString();
|
||||||
this._id = _id;
|
this._id = _id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String hash() {
|
|
||||||
return Hashing.sha1().hashString(action + collection + _id + data.toString(), Charsets.UTF_8).toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public JSONObject toJSON() {
|
public JSONObject toJSON() {
|
||||||
JSONObject object = new JSONObject();
|
JSONObject object = new JSONObject();
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
|
@ -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()
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
||||||
|
}
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,5 +90,5 @@ class ErrorDialog : DialogFragment() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun stopAlarm() =
|
private fun stopAlarm() =
|
||||||
MainApp.instance().stopService(Intent(MainApp.instance().applicationContext, AlarmSoundService::class.java))
|
MainApp.instance().stopService(Intent(MainApp.instance().applicationContext, AlarmSoundService::class.java))
|
||||||
}
|
}
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
|
@ -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?
|
||||||
|
@ -62,22 +62,14 @@ class ProfileViewerDialog : DialogFragment() {
|
||||||
profile = TreatmentsPlugin.getPlugin().getProfileSwitchFromHistory(time)?.profileObject
|
profile = TreatmentsPlugin.getPlugin().getProfileSwitchFromHistory(time)?.profileObject
|
||||||
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()
|
Mode.CUSTOM_PROFILE -> {
|
||||||
profileName = (ConfigBuilderPlugin.getPlugin().activePump as ProfileInterface?)?.profileName
|
|
||||||
date = ""
|
|
||||||
profileview_reload.visibility = View.VISIBLE
|
|
||||||
profileview_datelayout.visibility = View.GONE
|
|
||||||
}
|
|
||||||
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) {
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
|
@ -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,28 +73,28 @@ 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()
|
||||||
|
|
||||||
treatments_wizard_bg_input.setParams(savedInstanceState?.getDouble("treatments_wizard_bg_input")
|
treatments_wizard_bg_input.setParams(savedInstanceState?.getDouble("treatments_wizard_bg_input")
|
||||||
?: 0.0, 0.0, 500.0, 0.1, DecimalFormat("0.0"), false, ok, textWatcher)
|
?: 0.0, 0.0, 500.0, 0.1, DecimalFormat("0.0"), false, ok, textWatcher)
|
||||||
treatments_wizard_carbs_input.setParams(savedInstanceState?.getDouble("treatments_wizard_carbs_input")
|
treatments_wizard_carbs_input.setParams(savedInstanceState?.getDouble("treatments_wizard_carbs_input")
|
||||||
?: 0.0, 0.0, maxCarbs.toDouble(), 1.0, DecimalFormat("0"), false, ok, textWatcher)
|
?: 0.0, 0.0, maxCarbs.toDouble(), 1.0, DecimalFormat("0"), false, ok, textWatcher)
|
||||||
val bolusStep = ConfigBuilderPlugin.getPlugin().activePump?.pumpDescription?.bolusStep
|
val bolusStep = ConfigBuilderPlugin.getPlugin().activePump?.pumpDescription?.bolusStep
|
||||||
?: 0.1
|
?: 0.1
|
||||||
treatments_wizard_correction_input.setParams(savedInstanceState?.getDouble("treatments_wizard_correction_input")
|
treatments_wizard_correction_input.setParams(savedInstanceState?.getDouble("treatments_wizard_correction_input")
|
||||||
?: 0.0, -maxCorrection, maxCorrection, bolusStep, DecimalFormatter.pumpSupportedBolusFormat(), false, ok, textWatcher)
|
?: 0.0, -maxCorrection, maxCorrection, bolusStep, DecimalFormatter.pumpSupportedBolusFormat(), false, ok, textWatcher)
|
||||||
treatments_wizard_carb_time_input.setParams(savedInstanceState?.getDouble("treatments_wizard_carb_time_input")
|
treatments_wizard_carb_time_input.setParams(savedInstanceState?.getDouble("treatments_wizard_carb_time_input")
|
||||||
?: 0.0, -60.0, 60.0, 5.0, DecimalFormat("0"), false, ok, textWatcher)
|
?: 0.0, -60.0, 60.0, 5.0, DecimalFormat("0"), false, ok, textWatcher)
|
||||||
initDialog()
|
initDialog()
|
||||||
|
|
||||||
treatments_wizard_percent_used.text = MainApp.gs(R.string.format_percent, SP.getInt(R.string.key_boluswizard_percentage, 100))
|
treatments_wizard_percent_used.text = MainApp.gs(R.string.format_percent, SP.getInt(R.string.key_boluswizard_percentage, 100))
|
||||||
|
@ -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
|
||||||
|
@ -157,13 +147,13 @@ class WizardDialog : DialogFragment() {
|
||||||
}
|
}
|
||||||
// bus
|
// bus
|
||||||
disposable.add(RxBus
|
disposable.add(RxBus
|
||||||
.toObservable(EventAutosensCalculationFinished::class.java)
|
.toObservable(EventAutosensCalculationFinished::class.java)
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.subscribe({
|
.subscribe({
|
||||||
activity?.runOnUiThread { calculateInsulin() }
|
activity?.runOnUiThread { calculateInsulin() }
|
||||||
}, {
|
}, {
|
||||||
FabricPrivacy.logException(it)
|
FabricPrivacy.logException(it)
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
|
||||||
|
@ -291,15 +280,15 @@ class WizardDialog : DialogFragment() {
|
||||||
val carbTime = SafeParse.stringToInt(treatments_wizard_carb_time_input.text)
|
val carbTime = SafeParse.stringToInt(treatments_wizard_carb_time_input.text)
|
||||||
|
|
||||||
wizard = BolusWizard(specificProfile, profileName, tempTarget, carbsAfterConstraint, cob, bg, correction,
|
wizard = BolusWizard(specificProfile, profileName, tempTarget, carbsAfterConstraint, cob, bg, correction,
|
||||||
SP.getInt(R.string.key_boluswizard_percentage, 100).toDouble(),
|
SP.getInt(R.string.key_boluswizard_percentage, 100).toDouble(),
|
||||||
treatments_wizard_bgcheckbox.isChecked,
|
treatments_wizard_bgcheckbox.isChecked,
|
||||||
treatments_wizard_cobcheckbox.isChecked,
|
treatments_wizard_cobcheckbox.isChecked,
|
||||||
treatments_wizard_bolusiobcheckbox.isChecked,
|
treatments_wizard_bolusiobcheckbox.isChecked,
|
||||||
treatments_wizard_basaliobcheckbox.isChecked,
|
treatments_wizard_basaliobcheckbox.isChecked,
|
||||||
treatments_wizard_sbcheckbox.isChecked,
|
treatments_wizard_sbcheckbox.isChecked,
|
||||||
treatments_wizard_ttcheckbox.isChecked,
|
treatments_wizard_ttcheckbox.isChecked,
|
||||||
treatments_wizard_bgtrendcheckbox.isChecked,
|
treatments_wizard_bgtrendcheckbox.isChecked,
|
||||||
treatment_wizard_notes.text.toString(), carbTime)
|
treatment_wizard_notes.text.toString(), carbTime)
|
||||||
|
|
||||||
wizard?.let { wizard ->
|
wizard?.let { wizard ->
|
||||||
treatments_wizard_bg.text = String.format(MainApp.gs(R.string.format_bg_isf), BgReading().value(Profile.toMgdl(bg, ProfileFunctions.getSystemUnits())).valueToUnitsToString(ProfileFunctions.getSystemUnits()), wizard.sens)
|
treatments_wizard_bg.text = String.format(MainApp.gs(R.string.format_bg_isf), BgReading().value(Profile.toMgdl(bg, ProfileFunctions.getSystemUnits())).valueToUnitsToString(ProfileFunctions.getSystemUnits()), wizard.sens)
|
||||||
|
@ -320,8 +309,8 @@ class WizardDialog : DialogFragment() {
|
||||||
// Trend
|
// Trend
|
||||||
if (treatments_wizard_bgtrendcheckbox.isChecked && wizard.glucoseStatus != null) {
|
if (treatments_wizard_bgtrendcheckbox.isChecked && wizard.glucoseStatus != null) {
|
||||||
treatments_wizard_bgtrend.text = ((if (wizard.trend > 0) "+" else "")
|
treatments_wizard_bgtrend.text = ((if (wizard.trend > 0) "+" else "")
|
||||||
+ Profile.toUnitsString(wizard.trend * 3, wizard.trend * 3 / Constants.MMOLL_TO_MGDL, ProfileFunctions.getSystemUnits())
|
+ Profile.toUnitsString(wizard.trend * 3, wizard.trend * 3 / Constants.MMOLL_TO_MGDL, ProfileFunctions.getSystemUnits())
|
||||||
+ " " + ProfileFunctions.getSystemUnits())
|
+ " " + ProfileFunctions.getSystemUnits())
|
||||||
} else {
|
} else {
|
||||||
treatments_wizard_bgtrend.text = ""
|
treatments_wizard_bgtrend.text = ""
|
||||||
}
|
}
|
|
@ -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)
|
performPluginSwitch(newState, type);
|
||||||
.setPositiveButton(R.string.yes, (dialog, id) -> {
|
SP.putBoolean("allow_hardware_pump", true);
|
||||||
performPluginSwitch(newState, type);
|
if (L.isEnabled(L.PUMP))
|
||||||
SP.putBoolean("allow_hardware_pump", true);
|
log.debug("First time HW pump allowed!");
|
||||||
if (L.isEnabled(L.PUMP))
|
}, () -> {
|
||||||
log.debug("First time HW pump allowed!");
|
RxBus.INSTANCE.send(new EventConfigBuilderUpdateGui());
|
||||||
})
|
if (L.isEnabled(L.PUMP))
|
||||||
.setNegativeButton(R.string.cancel, (dialog, id) -> {
|
log.debug("User does not allow switching to HW pump!");
|
||||||
RxBus.INSTANCE.send(new EventConfigBuilderUpdateGui());
|
});
|
||||||
if (L.isEnabled(L.PUMP))
|
|
||||||
log.debug("User does not allow switching to HW pump!");
|
|
||||||
});
|
|
||||||
builder.create().show();
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
performPluginSwitch(newState, type);
|
performPluginSwitch(newState, type);
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
}
|
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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 {
|
||||||
|
|
|
@ -72,13 +72,13 @@ class ObjectivesFragment : Fragment() {
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
disposable.add(RxBus
|
disposable.add(RxBus
|
||||||
.toObservable(EventObjectivesUpdateGui::class.java)
|
.toObservable(EventObjectivesUpdateGui::class.java)
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.subscribe({
|
.subscribe({
|
||||||
objectives_recyclerview.adapter?.notifyDataSetChanged()
|
objectives_recyclerview.adapter?.notifyDataSetChanged()
|
||||||
}, {
|
}, {
|
||||||
FabricPrivacy.logException(it)
|
FabricPrivacy.logException(it)
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 ->
|
||||||
objective.startedOn = 0
|
OKDialog.showConfirmation(activity, MainApp.gs(R.string.objectives), MainApp.gs(R.string.doyouwantresetstart), Runnable {
|
||||||
scrollToCurrentObjective()
|
objective.startedOn = 0
|
||||||
RxBus.send(EventObjectivesUpdateGui())
|
scrollToCurrentObjective()
|
||||||
RxBus.send(EventSWUpdate(false))
|
RxBus.send(EventObjectivesUpdateGui())
|
||||||
|
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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -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)
|
||||||
|
|
||||||
|
}
|
|
@ -1,11 +0,0 @@
|
||||||
package info.nightscout.androidaps.plugins.general.actions.defs;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by andy on 9/20/18.
|
|
||||||
*/
|
|
||||||
|
|
||||||
public interface CustomActionType {
|
|
||||||
|
|
||||||
String getKey();
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
package info.nightscout.androidaps.plugins.general.actions.defs
|
||||||
|
|
||||||
|
interface CustomActionType {
|
||||||
|
val key: String?
|
||||||
|
}
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
instantiateAction()?.let {
|
||||||
dismiss()
|
RxBus.send(EventAutomationAddAction(it))
|
||||||
instantiateAction()?.let {
|
RxBus.send(EventAutomationUpdateGui())
|
||||||
RxBus.send(EventAutomationAddAction(it))
|
|
||||||
RxBus.send(EventAutomationUpdateGui())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return true
|
||||||
// Cancel button
|
|
||||||
cancel.setOnClickListener { dismiss() }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onStart() {
|
override fun onSaveInstanceState(savedInstanceState: Bundle) {
|
||||||
super.onStart()
|
super.onSaveInstanceState(savedInstanceState)
|
||||||
dialog?.window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
|
savedInstanceState.putInt("checkedIndex", determineCheckedIndex())
|
||||||
}
|
|
||||||
|
|
||||||
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
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
|
||||||
ok.setOnClickListener {
|
|
||||||
dismiss()
|
|
||||||
instantiateTrigger()?.let {
|
|
||||||
clickListener?.onClick(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cancel button
|
|
||||||
cancel.setOnClickListener { dismiss() }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onStart() {
|
override fun submit(): Boolean {
|
||||||
super.onStart()
|
instantiateTrigger()?.let {
|
||||||
dialog?.window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
|
clickListener?.onClick(it)
|
||||||
|
}
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
|
||||||
ok.setOnClickListener {
|
|
||||||
dismiss()
|
|
||||||
action?.let {
|
|
||||||
RxBus.send(EventAutomationUpdateAction(it, actionPosition))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cancel button
|
|
||||||
cancel.setOnClickListener { dismiss() }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onStart() {
|
override fun submit(): Boolean {
|
||||||
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)
|
RxBus.send(EventAutomationUpdateAction(it, actionPosition))
|
||||||
bundle.putString("action", it.toJSON())
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSaveInstanceState(savedInstanceState: Bundle) {
|
||||||
|
super.onSaveInstanceState(savedInstanceState)
|
||||||
|
action?.let {
|
||||||
|
savedInstanceState.putInt("actionPosition", actionPosition)
|
||||||
|
savedInstanceState.putString("action", it.toJSON())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
|
||||||
ok.setOnClickListener {
|
|
||||||
dismiss()
|
|
||||||
trigger?.let { trigger -> RxBus.send(EventAutomationUpdateTrigger(trigger)) }
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cancel button
|
|
||||||
cancel.setOnClickListener { dismiss() }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onStart() {
|
override fun submit():Boolean {
|
||||||
super.onStart()
|
trigger?.let { trigger -> RxBus.send(EventAutomationUpdateTrigger(trigger)) }
|
||||||
dialog?.window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onSaveInstanceState(bundle: Bundle) {
|
override fun onSaveInstanceState(savedInstanceState: Bundle) {
|
||||||
super.onSaveInstanceState(bundle)
|
super.onSaveInstanceState(savedInstanceState)
|
||||||
trigger?.let { bundle.putString("trigger", it.toJSON()) }
|
trigger?.let { savedInstanceState.putString("trigger", it.toJSON()) }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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;
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,61 +696,25 @@ public class NewNSTreatmentDialog extends AppCompatDialogFragment implements Vie
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void confirmNSTreatmentCreation() {
|
private void confirmNSTreatmentCreation() {
|
||||||
Context context = getContext();
|
final JSONObject data = gatherData();
|
||||||
if (context != null) {
|
OKDialog.showConfirmation(getContext(), Translator.translate(JsonHelper.safeGetString(data, "eventType", MainApp.gs(R.string.overview_treatment_label))), buildConfirmText(data), () -> createNSTreatment(data));
|
||||||
final JSONObject data = gatherData();
|
|
||||||
final String confirmText = buildConfirmText(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"));
|
profileStore,
|
||||||
}
|
JsonHelper.safeGetString(data, "profile"),
|
||||||
} else if (options.executeTempTarget) {
|
JsonHelper.safeGetInt(data, "duration"),
|
||||||
final int duration = JsonHelper.safeGetInt(data, "duration");
|
JsonHelper.safeGetInt(data, "percentage"),
|
||||||
final double targetBottom = JsonHelper.safeGetDouble(data, "targetBottom");
|
JsonHelper.safeGetInt(data, "timeshift"),
|
||||||
final double targetTop = JsonHelper.safeGetDouble(data, "targetTop");
|
eventTime.getTime()
|
||||||
final String reason = JsonHelper.safeGetString(data, "reason", "");
|
);
|
||||||
if ((targetBottom != 0d && targetTop != 0d) || duration == 0) {
|
NSUpload.uploadProfileSwitch(profileSwitch);
|
||||||
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 {
|
} else {
|
||||||
if (JsonHelper.safeGetString(data, "eventType").equals(CareportalEvent.PROFILESWITCH)) {
|
NSUpload.uploadCareportalEntryToNS(data);
|
||||||
ProfileSwitch profileSwitch = ProfileFunctions.prepareProfileSwitch(
|
|
||||||
profileStore,
|
|
||||||
JsonHelper.safeGetString(data, "profile"),
|
|
||||||
JsonHelper.safeGetInt(data, "duration"),
|
|
||||||
JsonHelper.safeGetInt(data, "percentage"),
|
|
||||||
JsonHelper.safeGetInt(data, "timeshift"),
|
|
||||||
eventTime.getTime()
|
|
||||||
);
|
|
||||||
NSUpload.uploadProfileSwitch(profileSwitch);
|
|
||||||
} else {
|
|
||||||
NSUpload.uploadCareportalEntryToNS(data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
filter.setText("");
|
||||||
public void onClick(View v) {
|
category.setSelection(0);
|
||||||
filter.setText("");
|
subcategory.setSelection(0);
|
||||||
category.setSelection(0);
|
filterData();
|
||||||
subcategory.setSelection(0);
|
|
||||||
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 -> {
|
||||||
|
final Food food = (Food) v.getTag();
|
||||||
|
OKDialog.showConfirmation(getContext(), MainApp.gs(R.string.confirmation), MainApp.gs(R.string.removerecord) + "\n" + food.name, (dialog, id) -> {
|
||||||
|
final String _id = food._id;
|
||||||
|
if (_id != null && !_id.equals("")) {
|
||||||
|
NSUpload.removeFoodFromNS(_id);
|
||||||
|
}
|
||||||
|
FoodPlugin.getPlugin().getService().delete(food);
|
||||||
|
}, null);
|
||||||
|
});
|
||||||
remove.setPaintFlags(remove.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG);
|
remove.setPaintFlags(remove.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
final Food food = (Food) v.getTag();
|
|
||||||
switch (v.getId()) {
|
|
||||||
|
|
||||||
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;
|
|
||||||
if (_id != null && !_id.equals("")) {
|
|
||||||
NSUpload.removeFoodFromNS(_id);
|
|
||||||
}
|
|
||||||
FoodPlugin.getPlugin().getService().delete(food);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
builder.setNegativeButton(MainApp.gs(R.string.cancel), null);
|
|
||||||
builder.show();
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,85 +58,71 @@ 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 + " ?")
|
try {
|
||||||
.setPositiveButton(android.R.string.yes, (dialog, which) -> {
|
FileWriter fw = new FileWriter(file);
|
||||||
|
PrintWriter pw = new PrintWriter(fw);
|
||||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(c);
|
Map<String, ?> prefsMap = prefs.getAll();
|
||||||
try {
|
for (Map.Entry<String, ?> entry : prefsMap.entrySet()) {
|
||||||
FileWriter fw = new FileWriter(file);
|
pw.println(entry.getKey() + "::" + entry.getValue().toString());
|
||||||
PrintWriter pw = new PrintWriter(fw);
|
}
|
||||||
Map<String, ?> prefsMap = prefs.getAll();
|
pw.close();
|
||||||
for (Map.Entry<String, ?> entry : prefsMap.entrySet()) {
|
fw.close();
|
||||||
pw.println(entry.getKey() + "::" + entry.getValue().toString());
|
ToastUtils.showToastInUiThread(context, MainApp.gs(R.string.exported));
|
||||||
}
|
} catch (FileNotFoundException e) {
|
||||||
pw.close();
|
ToastUtils.showToastInUiThread(context, MainApp.gs(R.string.filenotfound) + " " + file);
|
||||||
fw.close();
|
log.error("Unhandled exception", e);
|
||||||
ToastUtils.showToastInUiThread(c, MainApp.gs(R.string.exported));
|
} catch (IOException e) {
|
||||||
} catch (FileNotFoundException e) {
|
log.error("Unhandled exception", e);
|
||||||
ToastUtils.showToastInUiThread(c, MainApp.gs(R.string.filenotfound) + " " + file);
|
}
|
||||||
log.error("Unhandled exception", e);
|
});
|
||||||
} catch (IOException 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 + " ?")
|
String line;
|
||||||
.setPositiveButton(android.R.string.yes, (dialog, which) -> {
|
String[] lineParts;
|
||||||
|
try {
|
||||||
|
SP.clear();
|
||||||
|
|
||||||
String line;
|
BufferedReader reader = new BufferedReader(new FileReader(file));
|
||||||
String[] lineParts;
|
while ((line = reader.readLine()) != null) {
|
||||||
try {
|
lineParts = line.split("::");
|
||||||
SP.clear();
|
if (lineParts.length == 2) {
|
||||||
|
if (lineParts[1].equals("true") || lineParts[1].equals("false")) {
|
||||||
BufferedReader reader = new BufferedReader(new FileReader(file));
|
SP.putBoolean(lineParts[0], Boolean.parseBoolean(lineParts[1]));
|
||||||
while ((line = reader.readLine()) != null) {
|
} else {
|
||||||
lineParts = line.split("::");
|
SP.putString(lineParts[0], lineParts[1]);
|
||||||
if (lineParts.length == 2) {
|
|
||||||
if (lineParts[1].equals("true") || lineParts[1].equals("false")) {
|
|
||||||
SP.putBoolean(lineParts[0], Boolean.parseBoolean(lineParts[1]));
|
|
||||||
} else {
|
|
||||||
SP.putString(lineParts[0], lineParts[1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
reader.close();
|
|
||||||
SP.putBoolean(R.string.key_setupwizard_processed, true);
|
|
||||||
OKDialog.show(context, MainApp.gs(R.string.setting_imported), MainApp.gs(R.string.restartingapp), () -> {
|
|
||||||
log.debug("Exiting");
|
|
||||||
MainApp.instance().stopKeepAliveService();
|
|
||||||
RxBus.INSTANCE.send(new EventAppExit());
|
|
||||||
MainApp.closeDbHelper();
|
|
||||||
if (context instanceof Activity) {
|
|
||||||
((Activity)context).finish();
|
|
||||||
}
|
|
||||||
System.runFinalization();
|
|
||||||
System.exit(0);
|
|
||||||
});
|
|
||||||
} catch (FileNotFoundException e) {
|
|
||||||
ToastUtils.showToastInUiThread(context, MainApp.gs(R.string.filenotfound) + " " + file);
|
|
||||||
log.error("Unhandled exception", e);
|
|
||||||
} catch (IOException e) {
|
|
||||||
log.error("Unhandled exception", e);
|
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
.setNegativeButton(android.R.string.cancel, null)
|
reader.close();
|
||||||
.show();
|
SP.putBoolean(R.string.key_setupwizard_processed, true);
|
||||||
|
OKDialog.show(context, MainApp.gs(R.string.setting_imported), MainApp.gs(R.string.restartingapp), () -> {
|
||||||
|
log.debug("Exiting");
|
||||||
|
RxBus.INSTANCE.send(new EventAppExit());
|
||||||
|
if (context instanceof Activity) {
|
||||||
|
((Activity) context).finish();
|
||||||
|
}
|
||||||
|
System.runFinalization();
|
||||||
|
System.exit(0);
|
||||||
|
});
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
ToastUtils.showToastInUiThread(context, MainApp.gs(R.string.filenotfound) + " " + file);
|
||||||
|
log.error("Unhandled exception", e);
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("Unhandled exception", e);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
UploadQueue.clearQueue();
|
||||||
|
updateGui();
|
||||||
builder.setTitle(MainApp.gs(R.string.confirmation));
|
FabricPrivacy.getInstance().logCustom("NSClientClearQueue");
|
||||||
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();
|
|
||||||
updateGui();
|
|
||||||
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()));
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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;
|
||||||
|
|
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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
|
||||||
|
|
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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");
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -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))
|
||||||
|
|
|
@ -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) + " <<< " + "░ " + sms.phoneNumber + " <b>" + sms.text + "</b><br>"
|
logText += DateUtil.timeString(sms.date) + " <<< " + "░ " + sms.phoneNumber + " <b>" + sms.text + "</b><br>"
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue