Merge remote-tracking branch 'nico/dev-wip' into dev-nico

This commit is contained in:
TebbeUbben 2019-02-02 16:58:21 +01:00
commit cc189d360f
15 changed files with 370 additions and 27 deletions

View file

@ -9,6 +9,7 @@ import android.preference.PreferenceActivity;
import android.preference.PreferenceFragment;
import android.preference.PreferenceGroup;
import android.preference.PreferenceManager;
import android.preference.PreferenceScreen;
import android.text.TextUtils;
import info.nightscout.androidaps.Config;
@ -190,6 +191,17 @@ public class PreferencesActivity extends PreferenceActivity implements SharedPre
addPreferencesFromResourceIfEnabled(StatuslinePlugin.getPlugin(), PluginType.GENERAL);
}
if (Config.NSCLIENT) {
PreferenceScreen scrnAdvancedSettings = (PreferenceScreen)findPreference(getString(R.string.key_advancedsettings));
if (scrnAdvancedSettings != null) {
scrnAdvancedSettings.removePreference(getPreference(getString(R.string.key_statuslights_res_warning)));
scrnAdvancedSettings.removePreference(getPreference(getString(R.string.key_statuslights_res_critical)));
scrnAdvancedSettings.removePreference(getPreference(getString(R.string.key_statuslights_bat_warning)));
scrnAdvancedSettings.removePreference(getPreference(getString(R.string.key_statuslights_bat_critical)));
scrnAdvancedSettings.removePreference(getPreference(getString(R.string.key_show_statuslights)));
}
}
initSummary(getPreferenceScreen());
}

View file

@ -90,8 +90,8 @@ public class CareportalEvent implements DataPointWithLabelInterface, Interval {
return System.currentTimeMillis() - date;
}
public long getHoursFromStart() {
return (System.currentTimeMillis() - date) / (60 * 60 * 1000);
public double getHoursFromStart() {
return (System.currentTimeMillis() - date) / (60 * 60 * 1000.0);
}
public String age() {

View file

@ -33,6 +33,10 @@ public interface PumpInterface {
double getBaseBasalRate(); // base basal rate, not temp basal
double getReservoirLevel();
int getBatteryLevel(); // in percent as integer
PumpEnactResult deliverTreatment(DetailedBolusInfo detailedBolusInfo);
void stopBolusDelivering();
PumpEnactResult setTempBasalAbsolute(Double absoluteRate, Integer durationInMinutes, Profile profile, boolean enforceNew);

View file

@ -3,6 +3,7 @@ package info.nightscout.androidaps.plugins.Overview;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.NotificationManager;
import android.arch.core.util.Function;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
@ -97,6 +98,7 @@ import info.nightscout.androidaps.plugins.Loop.LoopPlugin;
import info.nightscout.androidaps.plugins.Loop.events.EventNewOpenLoopNotification;
import info.nightscout.androidaps.plugins.NSClientInternal.NSUpload;
import info.nightscout.androidaps.plugins.NSClientInternal.data.NSDeviceStatus;
import info.nightscout.androidaps.plugins.NSClientInternal.data.NSSettingsStatus;
import info.nightscout.androidaps.plugins.Overview.Dialogs.CalibrationDialog;
import info.nightscout.androidaps.plugins.Overview.Dialogs.ErrorHelperActivity;
import info.nightscout.androidaps.plugins.Overview.Dialogs.NewCarbsDialog;
@ -162,6 +164,13 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
TextView sage;
TextView pbage;
TextView iageView;
TextView cageView;
TextView reservoirView;
TextView sageView;
TextView batteryView;
LinearLayout statuslightsLayout;
RecyclerView notificationsView;
LinearLayoutManager llm;
@ -258,6 +267,13 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
sage = (TextView) view.findViewById(R.id.careportal_sensorage);
pbage = (TextView) view.findViewById(R.id.careportal_pbage);
iageView = (TextView) view.findViewById(R.id.overview_insulinage);
cageView = (TextView) view.findViewById(R.id.overview_canulaage);
reservoirView = (TextView) view.findViewById(R.id.overview_reservoirlevel);
sageView = (TextView) view.findViewById(R.id.overview_sensorage);
batteryView = (TextView) view.findViewById(R.id.overview_batterylevel);
statuslightsLayout = (LinearLayout) view.findViewById(R.id.overview_statuslights);
bgGraph = (GraphView) view.findViewById(R.id.overview_bggraph);
iobGraph = (GraphView) view.findViewById(R.id.overview_iobgraph);
@ -1105,25 +1121,25 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
final LoopPlugin.LastRun finalLastRun = LoopPlugin.lastRun;
if (Config.APS && pump.getPumpDescription().isTempBasalCapable) {
apsModeView.setVisibility(View.VISIBLE);
apsModeView.setBackgroundColor(MainApp.gc(R.color.loopenabled));
apsModeView.setTextColor(Color.BLACK);
apsModeView.setBackgroundColor(MainApp.gc(R.color.ribbonDefault));
apsModeView.setTextColor(MainApp.gc(R.color.ribbonTextDefault));
final LoopPlugin loopPlugin = LoopPlugin.getPlugin();
if (loopPlugin.isEnabled(PluginType.LOOP) && loopPlugin.isSuperBolus()) {
apsModeView.setBackgroundColor(MainApp.gc(R.color.looppumpsuspended));
apsModeView.setBackgroundColor(MainApp.gc(R.color.ribbonWarning));
apsModeView.setText(String.format(MainApp.gs(R.string.loopsuperbolusfor), loopPlugin.minutesToEndOfSuspend()));
apsModeView.setTextColor(Color.WHITE);
apsModeView.setTextColor(MainApp.gc(R.color.ribbonTextWarning));
} else if (loopPlugin.isDisconnected()) {
apsModeView.setBackgroundColor(MainApp.gc(R.color.looppumpsuspended));
apsModeView.setBackgroundColor(MainApp.gc(R.color.ribbonCritical));
apsModeView.setText(String.format(MainApp.gs(R.string.loopdisconnectedfor), loopPlugin.minutesToEndOfSuspend()));
apsModeView.setTextColor(Color.WHITE);
apsModeView.setTextColor(MainApp.gc(R.color.ribbonTextCritical));
} else if (loopPlugin.isEnabled(PluginType.LOOP) && loopPlugin.isSuspended()) {
apsModeView.setBackgroundColor(MainApp.gc(R.color.looppumpsuspended));
apsModeView.setBackgroundColor(MainApp.gc(R.color.ribbonWarning));
apsModeView.setText(String.format(MainApp.gs(R.string.loopsuspendedfor), loopPlugin.minutesToEndOfSuspend()));
apsModeView.setTextColor(Color.WHITE);
apsModeView.setTextColor(MainApp.gc(R.color.ribbonTextWarning));
} else if (pump.isSuspended()) {
apsModeView.setBackgroundColor(MainApp.gc(R.color.looppumpsuspended));
apsModeView.setBackgroundColor(MainApp.gc(R.color.ribbonWarning));
apsModeView.setText(MainApp.gs(R.string.pumpsuspended));
apsModeView.setTextColor(Color.WHITE);
apsModeView.setTextColor(MainApp.gc(R.color.ribbonTextWarning));
} else if (loopPlugin.isEnabled(PluginType.LOOP)) {
if (closedLoopEnabled.value()) {
apsModeView.setText(MainApp.gs(R.string.closedloop));
@ -1131,9 +1147,9 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
apsModeView.setText(MainApp.gs(R.string.openloop));
}
} else {
apsModeView.setBackgroundColor(MainApp.gc(R.color.loopdisabled));
apsModeView.setBackgroundColor(MainApp.gc(R.color.ribbonCritical));
apsModeView.setText(MainApp.gs(R.string.disabledloop));
apsModeView.setTextColor(Color.WHITE);
apsModeView.setTextColor(MainApp.gc(R.color.ribbonTextCritical));
}
} else {
apsModeView.setVisibility(View.GONE);
@ -1142,13 +1158,13 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
// temp target
TempTarget tempTarget = TreatmentsPlugin.getPlugin().getTempTargetFromHistory();
if (tempTarget != null) {
tempTargetView.setTextColor(Color.BLACK);
tempTargetView.setBackgroundColor(MainApp.gc(R.color.tempTargetBackground));
tempTargetView.setTextColor(MainApp.gc(R.color.ribbonTextWarning));
tempTargetView.setBackgroundColor(MainApp.gc(R.color.ribbonWarning));
tempTargetView.setVisibility(View.VISIBLE);
tempTargetView.setText(Profile.toTargetRangeString(tempTarget.low, tempTarget.high, Constants.MGDL, units) + " " + DateUtil.untilString(tempTarget.end()));
} else {
tempTargetView.setTextColor(Color.WHITE);
tempTargetView.setBackgroundColor(MainApp.gc(R.color.tempTargetDisabledBackground));
tempTargetView.setTextColor(MainApp.gc(R.color.ribbonTextDefault));
tempTargetView.setBackgroundColor(MainApp.gc(R.color.ribbonDefault));
tempTargetView.setText(Profile.toTargetRangeString(profile.getTargetLow(), profile.getTargetHigh(), units, units));
tempTargetView.setVisibility(View.VISIBLE);
}
@ -1247,7 +1263,13 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
}
activeProfileView.setText(ProfileFunctions.getInstance().getProfileName());
activeProfileView.setBackgroundColor(Color.GRAY);
if (profile.getPercentage() != 100 || profile.getTimeshift() != 0) {
activeProfileView.setBackgroundColor(MainApp.gc(R.color.ribbonWarning));
activeProfileView.setTextColor(MainApp.gc(R.color.ribbonTextWarning));
} else {
activeProfileView.setBackgroundColor(MainApp.gc(R.color.ribbonDefault));
activeProfileView.setTextColor(MainApp.gc(R.color.ribbonTextDefault));
}
// QuickWizard button
QuickWizardEntry quickWizardEntry = OverviewPlugin.getPlugin().quickWizard.getActive();
@ -1352,6 +1374,56 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
cobView.setText(cobText);
}
if (statuslightsLayout != null) {
if (SP.getBoolean(R.string.key_show_statuslights, false)) {
CareportalEvent careportalEvent;
NSSettingsStatus nsSettings = new NSSettingsStatus().getInstance();
double iageUrgent = nsSettings.getExtendedWarnValue("iage", "urgent", 96);
double iageWarn = nsSettings.getExtendedWarnValue("iage", "warn", 72);
double cageUrgent = nsSettings.getExtendedWarnValue("cage", "urgent", 72);
double cageWarn = nsSettings.getExtendedWarnValue("cage", "warn", 48);
double sageUrgent = nsSettings.getExtendedWarnValue("sage", "urgent", 166);
double sageWarn = nsSettings.getExtendedWarnValue("sage", "warn", 164);
//double pbageUrgent = nsSettings.getExtendedWarnValue("pgage", "urgent", 360);
//double pbageWarn = nsSettings.getExtendedWarnValue("pgage", "warn", 240);
double batUrgent = SP.getDouble(R.string.key_statuslights_bat_critical, 5.0);
double batWarn = SP.getDouble(R.string.key_statuslights_bat_warning, 25.0);
double resUrgent = SP.getDouble(R.string.key_statuslights_res_critical, 10.0);
double resWarn = SP.getDouble(R.string.key_statuslights_res_warning, 80.0);
if (cageView != null) {
careportalEvent = MainApp.getDbHelper().getLastCareportalEvent(CareportalEvent.SITECHANGE);
double canAge = careportalEvent != null ? careportalEvent.getHoursFromStart() : Double.MAX_VALUE;
applyStatuslight(cageView, "CAN", canAge, cageWarn, cageUrgent, Double.MAX_VALUE, true);
}
if (iageView != null) {
careportalEvent = MainApp.getDbHelper().getLastCareportalEvent(CareportalEvent.INSULINCHANGE);
double insulinAge = careportalEvent != null ? careportalEvent.getHoursFromStart() : Double.MAX_VALUE;
applyStatuslight(iageView, "INS", insulinAge, iageWarn, iageUrgent, Double.MAX_VALUE, true);
}
if (reservoirView != null) {
double reservoirLevel = pump.isInitialized() ? pump.getReservoirLevel() : -1;
applyStatuslight(reservoirView, "RES", reservoirLevel, resWarn, resUrgent, -1, false);
}
if (sageView != null) {
careportalEvent = MainApp.getDbHelper().getLastCareportalEvent(CareportalEvent.SENSORCHANGE);
double sensorAge = careportalEvent != null ? careportalEvent.getHoursFromStart() : Double.MAX_VALUE;
applyStatuslight(sageView, "SEN", sensorAge, sageWarn, sageUrgent, Double.MAX_VALUE, true);
}
if (batteryView != null) {
double batteryLevel = pump.isInitialized() ? pump.getBatteryLevel() : -1;
applyStatuslight(batteryView, "BAT", batteryLevel, batWarn, batUrgent, -1, false);
}
statuslightsLayout.setVisibility(View.VISIBLE);
} else {
statuslightsLayout.setVisibility(View.GONE);
}
}
boolean predictionsAvailable;
if (Config.APS)
predictionsAvailable = finalLastRun != null && finalLastRun.request.hasPredictions;
@ -1542,4 +1614,21 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
}
}
public static void applyStatuslight(TextView view, String text, double value, double warnThreshold, double urgentThreshold, double invalid, boolean checkAscending) {
Function<Double, Boolean> check = checkAscending ? (Double threshold) -> value >= threshold : (Double threshold) -> value <= threshold;
if (value != invalid) {
view.setText(text);
if (check.apply(urgentThreshold)) {
view.setTextColor(MainApp.gc(R.color.ribbonCritical));
} else if (check.apply(warnThreshold)) {
view.setTextColor(MainApp.gc(R.color.ribbonWarning));
} else {
view.setTextColor(MainApp.gc(R.color.ribbonDefault));
}
view.setVisibility(View.VISIBLE);
} else {
view.setVisibility(View.GONE);
}
}
}

View file

@ -435,6 +435,23 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint
return pump.basalProfile.hourlyRates[currentHour];
}
@Override
public double getReservoirLevel() {
return pump.reservoirLevel;
}
@Override
public int getBatteryLevel() {
switch (pump.state.batteryState) {
case PumpState.EMPTY:
return 5;
case PumpState.LOW:
return 25;
default:
return 100;
}
}
private static BolusProgressReporter bolusProgressReporter = (state, percent, delivered) -> {
EventOverviewBolusProgress event = EventOverviewBolusProgress.getInstance();
switch (state) {

View file

@ -152,6 +152,12 @@ public abstract class AbstractDanaRPlugin extends PluginBase implements PumpInte
return DanaRPump.getInstance().currentBasal;
}
@Override
public double getReservoirLevel() { return DanaRPump.getInstance().reservoirRemainingUnits; }
@Override
public int getBatteryLevel() { return DanaRPump.getInstance().batteryRemaining; }
@Override
public void stopBolusDelivering() {
if (sExecutionService == null) {

View file

@ -373,6 +373,12 @@ public class DanaRSPlugin extends PluginBase implements PumpInterface, DanaRInte
return DanaRPump.getInstance().currentBasal;
}
@Override
public double getReservoirLevel() { return DanaRPump.getInstance().reservoirRemainingUnits; }
@Override
public int getBatteryLevel() { return DanaRPump.getInstance().batteryRemaining; }
@Override
public synchronized PumpEnactResult deliverTreatment(DetailedBolusInfo detailedBolusInfo) {
detailedBolusInfo.insulin = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(detailedBolusInfo.insulin)).value();

View file

@ -408,6 +408,12 @@ public class InsightPlugin extends PluginBase implements PumpInterface, Constrai
return basalRate;
}
@Override
public double getReservoirLevel() { return reservoirInUnits; }
@Override
public int getBatteryLevel() { return batteryPercent; }
public String getBaseBasalRateString() {
final DecimalFormat df = new DecimalFormat("#.##");
return df.format(basalRate);

View file

@ -136,6 +136,12 @@ public class MDIPlugin extends PluginBase implements PumpInterface {
return 0d;
}
@Override
public double getReservoirLevel() { return -1; }
@Override
public int getBatteryLevel() { return -1; }
@Override
public PumpEnactResult deliverTreatment(DetailedBolusInfo detailedBolusInfo) {
PumpEnactResult result = new PumpEnactResult();

View file

@ -225,6 +225,12 @@ public class VirtualPumpPlugin extends PluginBase implements PumpInterface {
}
@Override
public double getReservoirLevel() { return reservoirInUnits; }
@Override
public int getBatteryLevel() { return batteryPercent; }
@Override
public PumpEnactResult deliverTreatment(DetailedBolusInfo detailedBolusInfo) {

View file

@ -183,6 +183,65 @@
</LinearLayout>
<LinearLayout
android:id="@+id/overview_statuslights"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:orientation="horizontal">
<TextView
android:id="@+id/overview_canulaage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingHorizontal="5dp"
android:layout_marginHorizontal="3dp"
android:gravity="center"
android:text=""
android:textSize="14sp" />
<TextView
android:id="@+id/overview_insulinage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingHorizontal="5dp"
android:layout_marginHorizontal="3dp"
android:gravity="center"
android:text=""
android:textSize="14sp" />
<TextView
android:id="@+id/overview_reservoirlevel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingHorizontal="5dp"
android:layout_marginHorizontal="3dp"
android:gravity="center"
android:text=""
android:textSize="14sp" />
<TextView
android:id="@+id/overview_sensorage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingHorizontal="5dp"
android:layout_marginHorizontal="3dp"
android:gravity="center"
android:text=""
android:textSize="14sp" />
<TextView
android:id="@+id/overview_batterylevel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingHorizontal="5dp"
android:layout_marginHorizontal="3dp"
android:gravity="center"
android:text=""
android:textSize="14sp" />
</LinearLayout>
<TextView
android:id="@+id/overview_extendedbolus"
android:layout_width="match_parent"

View file

@ -183,6 +183,65 @@
</LinearLayout>
<LinearLayout
android:id="@+id/overview_statuslights"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:orientation="horizontal">
<TextView
android:id="@+id/overview_canulaage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingHorizontal="5dp"
android:layout_marginHorizontal="3dp"
android:gravity="center"
android:text=""
android:textSize="14sp" />
<TextView
android:id="@+id/overview_insulinage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingHorizontal="5dp"
android:layout_marginHorizontal="3dp"
android:gravity="center"
android:text=""
android:textSize="14sp" />
<TextView
android:id="@+id/overview_reservoirlevel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingHorizontal="5dp"
android:layout_marginHorizontal="3dp"
android:gravity="center"
android:text=""
android:textSize="14sp" />
<TextView
android:id="@+id/overview_sensorage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingHorizontal="5dp"
android:layout_marginHorizontal="3dp"
android:gravity="center"
android:text=""
android:textSize="14sp" />
<TextView
android:id="@+id/overview_batterylevel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingHorizontal="5dp"
android:layout_marginHorizontal="3dp"
android:gravity="center"
android:text=""
android:textSize="14sp" />
</LinearLayout>
<TextView
android:id="@+id/overview_extendedbolus"
android:layout_width="match_parent"

View file

@ -60,10 +60,6 @@
<color name="colorScheduled">#de7550</color>
<color name="colorActive">#25912e</color>
<color name="loopenabled">#47c8ff</color>
<color name="loopdisabled">#FFDD7792</color>
<color name="looppumpsuspended">#ff0400</color>
<color name="notificationAnnouncement">#FF8C00</color>
<color name="notificationUrgent">#ff0400</color>
<color name="notificationNormal">#ff5e55</color>
@ -76,5 +72,12 @@
<color name="deviationred">#72FF0000</color>
<color name="deviationblack">#72000000</color>
<color name="ribbonDefault">#5a595b</color>
<color name="ribbonWarning">#f4d700</color>
<color name="ribbonCritical">#ff0400</color>
<color name="ribbonTextDefault">#FFFFFF</color>
<color name="ribbonTextWarning">#303030</color>
<color name="ribbonTextCritical">#FFFFFF</color>
<color name="ic_launcher_background">#424242</color>
</resources>

View file

@ -479,6 +479,7 @@
<string name="always_use_shortavg">Always use short average delta instead of simple delta</string>
<string name="always_use_shortavg_summary">Useful when data from unfiltered sources like xDrip gets noisy.</string>
<string name="advancedsettings_title">Advanced Settings</string>
<string name="key_advancedsettings" translatable="false">key_advancedsettings</string>
<string name="danar_model">Model: %1$02X Protocol: %2$02X Code: %3$02X</string>
<string name="profile">Profile</string>
<string name="openapsama_max_daily_safety_multiplier_summary">Default value: 3 This is a key OpenAPS safety cap. What this does is limit your basals to be 3x (in this people) your biggest basal rate. You likely will not need to change this, but you should be aware thats what is discussed about “3x max daily; 4x current” for safety caps.</string>
@ -605,6 +606,17 @@
<string name="key_usesuperbolus" translatable="false">key_usersuperbolus</string>
<string name="enablesuperbolus">Enable superbolus in wizard</string>
<string name="enablesuperbolus_summary">Enable superbolus functionality in wizard. Do not enable until you learn what it really does. IT MAY CAUSE INSULIN OVERDOSE IF USED BLINDLY!</string>
<string name="key_show_statuslights" translatable="false">key_show_statuslights</string>
<string name="show_statuslights">Show status lights on home screen</string>
<string name="show_statuslights_summary">Enable status lights for cage, iage, sage, reservoir and battery level on home screen.</string>
<string name="key_statuslights_res_warning" translatable="false">key_statuslights_res_warning</string>
<string name="statuslights_res_warning">Threshold warning reservoir level [U]</string>
<string name="key_statuslights_res_critical" translatable="false">key_statuslights_res_critical</string>
<string name="statuslights_res_critical">Threshold critical reservoir level [U]</string>
<string name="key_statuslights_bat_warning" translatable="false">key_statuslights_bat_warning</string>
<string name="statuslights_bat_warning">Threshold warning battery level [%]</string>
<string name="key_statuslights_bat_critical" translatable="false">key_statuslights_bat_critical</string>
<string name="statuslights_bat_critical">Threshold critical battery level [%]</string>
<string name="iob">IOB</string>
<string name="cob">COB</string>
<string name="virtualpump_firmware_label">Firmware</string>

View file

@ -141,7 +141,7 @@
<intent android:action="info.nightscout.androidaps.plugins.Overview.activities.QuickWizardListActivity" />
</Preference>
<PreferenceScreen android:title="@string/advancedsettings_title">
<PreferenceScreen android:title="@string/advancedsettings_title" android:key="@string/key_advancedsettings">
<SwitchPreference
android:defaultValue="false"
@ -149,6 +149,64 @@
android:summary="@string/enablesuperbolus_summary"
android:title="@string/enablesuperbolus" />
<SwitchPreference
android:defaultValue="false"
android:key="@string/key_show_statuslights"
android:summary="@string/show_statuslights_summary"
android:title="@string/show_statuslights" />
<com.andreabaccega.widget.ValidatingEditTextPreference
android:defaultValue="80"
android:dependency="@string/key_show_statuslights"
android:inputType="numberSigned"
android:key="@string/key_statuslights_res_warning"
android:maxLines="20"
android:selectAllOnFocus="true"
android:singleLine="true"
android:title="@string/statuslights_res_warning"
validate:maxNumber="300"
validate:minNumber="0"
validate:testType="numericRange" />
<com.andreabaccega.widget.ValidatingEditTextPreference
android:defaultValue="10"
android:dependency="@string/key_show_statuslights"
android:inputType="numberSigned"
android:key="@string/key_statuslights_res_critical"
android:maxLines="20"
android:selectAllOnFocus="true"
android:singleLine="true"
android:title="@string/statuslights_res_critical"
validate:maxNumber="300"
validate:minNumber="0"
validate:testType="numericRange" />
<com.andreabaccega.widget.ValidatingEditTextPreference
android:defaultValue="25"
android:dependency="@string/key_show_statuslights"
android:inputType="numberSigned"
android:key="@string/key_statuslights_bat_warning"
android:maxLines="20"
android:selectAllOnFocus="true"
android:singleLine="true"
android:title="@string/statuslights_bat_warning"
validate:maxNumber="100"
validate:minNumber="0"
validate:testType="numericRange" />
<com.andreabaccega.widget.ValidatingEditTextPreference
android:defaultValue="5"
android:dependency="@string/key_show_statuslights"
android:inputType="numberSigned"
android:key="@string/key_statuslights_bat_critical"
android:maxLines="20"
android:selectAllOnFocus="true"
android:singleLine="true"
android:title="@string/statuslights_bat_critical"
validate:maxNumber="100"
validate:minNumber="0"
validate:testType="numericRange" />
</PreferenceScreen>
</PreferenceCategory>