IDE: implement (crude) range checking for floating point property editor. Only show "Infinity not allowed" if user actually types +/-Inf.

This commit is contained in:
Bart 2022-10-08 22:52:19 +02:00
parent a582043e34
commit 26d083e55e
23 changed files with 134 additions and 1 deletions

View File

@ -1325,6 +1325,10 @@ msgstr ""
msgid "Value:"
msgstr "Valor"
#: objinspstrconsts.oisvalueoutofrange
msgid "Property value out of range."
msgstr ""
#: objinspstrconsts.oisvariant
msgid "Variant"
msgstr "Variant"

View File

@ -1289,6 +1289,10 @@ msgstr "Odznač vše"
msgid "Value:"
msgstr "Hodnota:"
#: objinspstrconsts.oisvalueoutofrange
msgid "Property value out of range."
msgstr ""
#: objinspstrconsts.oisvariant
msgid "Variant"
msgstr "Proměnlivý typ"

View File

@ -1287,6 +1287,10 @@ msgstr "Alles abwählen"
msgid "Value:"
msgstr "Wert:"
#: objinspstrconsts.oisvalueoutofrange
msgid "Property value out of range."
msgstr ""
#: objinspstrconsts.oisvariant
msgid "Variant"
msgstr "Variant"

View File

@ -1290,6 +1290,10 @@ msgstr "Deseleccionar Todo"
msgid "Value:"
msgstr "Valor:"
#: objinspstrconsts.oisvalueoutofrange
msgid "Property value out of range."
msgstr ""
#: objinspstrconsts.oisvariant
msgid "Variant"
msgstr "Variante"

View File

@ -1281,6 +1281,10 @@ msgstr "Poista valinta kaikista"
msgid "Value:"
msgstr "Arvo:"
#: objinspstrconsts.oisvalueoutofrange
msgid "Property value out of range."
msgstr ""
#: objinspstrconsts.oisvariant
msgid "Variant"
msgstr ""

View File

@ -1285,6 +1285,10 @@ msgstr "Tout désélectionner"
msgid "Value:"
msgstr "Valeur :"
#: objinspstrconsts.oisvalueoutofrange
msgid "Property value out of range."
msgstr ""
#: objinspstrconsts.oisvariant
msgid "Variant"
msgstr "Variant"

View File

@ -1331,6 +1331,10 @@ msgstr "בטל את כל הבחירות"
msgid "Value:"
msgstr "ערך:"
#: objinspstrconsts.oisvalueoutofrange
msgid "Property value out of range."
msgstr ""
#: objinspstrconsts.oisvariant
msgid "Variant"
msgstr "גירסה"

View File

@ -1288,6 +1288,10 @@ msgstr "Kijelölések megszüntetése"
msgid "Value:"
msgstr "Érték:"
#: objinspstrconsts.oisvalueoutofrange
msgid "Property value out of range."
msgstr ""
#: objinspstrconsts.oisvariant
msgid "Variant"
msgstr "Variáns"

View File

@ -1329,6 +1329,10 @@ msgstr ""
msgid "Value:"
msgstr "Nilai:"
#: objinspstrconsts.oisvalueoutofrange
msgid "Property value out of range."
msgstr ""
#: objinspstrconsts.oisvariant
msgid "Variant"
msgstr "Varian"

View File

@ -1291,6 +1291,10 @@ msgstr "Deseleziona tutto"
msgid "Value:"
msgstr "Valore:"
#: objinspstrconsts.oisvalueoutofrange
msgid "Property value out of range."
msgstr ""
#: objinspstrconsts.oisvariant
msgid "Variant"
msgstr "Variante"

View File

@ -1296,6 +1296,10 @@ msgstr "すべての選択を解除"
msgid "Value:"
msgstr "値:"
#: objinspstrconsts.oisvalueoutofrange
msgid "Property value out of range."
msgstr ""
#: objinspstrconsts.oisvariant
msgid "Variant"
msgstr "変数"

View File

@ -1289,6 +1289,10 @@ msgstr "Naikinti žymėjimą"
msgid "Value:"
msgstr "Reikšmė:"
#: objinspstrconsts.oisvalueoutofrange
msgid "Property value out of range."
msgstr ""
#: objinspstrconsts.oisvariant
msgid "Variant"
msgstr "Įvairaus tipo"

View File

@ -1316,6 +1316,10 @@ msgstr ""
msgid "Value:"
msgstr "Waarde:"
#: objinspstrconsts.oisvalueoutofrange
msgid "Property value out of range."
msgstr ""
#: objinspstrconsts.oisvariant
msgid "Variant"
msgstr "Variant"

View File

@ -1283,6 +1283,10 @@ msgstr ""
msgid "Value:"
msgstr "Wartość:"
#: objinspstrconsts.oisvalueoutofrange
msgid "Property value out of range."
msgstr ""
#: objinspstrconsts.oisvariant
msgid "Variant"
msgstr "Variant"

View File

@ -1275,6 +1275,10 @@ msgstr ""
msgid "Value:"
msgstr ""
#: objinspstrconsts.oisvalueoutofrange
msgid "Property value out of range."
msgstr ""
#: objinspstrconsts.oisvariant
msgid "Variant"
msgstr ""

View File

@ -1284,6 +1284,10 @@ msgstr "Desmarcar todos"
msgid "Value:"
msgstr "Valor:"
#: objinspstrconsts.oisvalueoutofrange
msgid "Property value out of range."
msgstr ""
#: objinspstrconsts.oisvariant
msgid "Variant"
msgstr "Variante"

View File

@ -1284,6 +1284,10 @@ msgstr "Снять выделение"
msgid "Value:"
msgstr "Значение:"
#: objinspstrconsts.oisvalueoutofrange
msgid "Property value out of range."
msgstr ""
#: objinspstrconsts.oisvariant
msgid "Variant"
msgstr "Variant"

View File

@ -1307,6 +1307,10 @@ msgstr ""
msgid "Value:"
msgstr "Hodnota:"
#: objinspstrconsts.oisvalueoutofrange
msgid "Property value out of range."
msgstr ""
#: objinspstrconsts.oisvariant
msgid "Variant"
msgstr "Variant"

View File

@ -1288,6 +1288,10 @@ msgstr "Tüm seçimleri kaldır"
msgid "Value:"
msgstr "Değer:"
#: objinspstrconsts.oisvalueoutofrange
msgid "Property value out of range."
msgstr ""
#: objinspstrconsts.oisvariant
msgid "Variant"
msgstr "Variant"

View File

@ -1291,6 +1291,10 @@ msgstr "Зняти вибір з всіх"
msgid "Value:"
msgstr "Значення:"
#: objinspstrconsts.oisvalueoutofrange
msgid "Property value out of range."
msgstr ""
#: objinspstrconsts.oisvariant
msgid "Variant"
msgstr "Variant"

View File

@ -1285,6 +1285,10 @@ msgstr "不选择所有"
msgid "Value:"
msgstr "值:"
#: objinspstrconsts.oisvalueoutofrange
msgid "Property value out of range."
msgstr ""
#: objinspstrconsts.oisvariant
msgid "Variant"
msgstr "变量"

View File

@ -375,6 +375,7 @@ resourcestring
oisInvalidPropertyValue = 'Invalid property value';
oisInfinityNotSupported = 'Setting a floating point property to positive or negative Infinity at design time is not supported';
oisNaNNotSupported = 'Setting a floating point property to NaN at design time is not supported';
oisValueOutOfRange = 'Property value out of range.';
oisNone = '(none)';
oisPressAKey = 'Press a key ...';
oisPressAKeyEGCtrlP = 'You can press e.g. Ctrl+P ...';

View File

@ -513,6 +513,8 @@ type
Single, Double, etc.) }
TFloatPropertyEditor = class(TPropertyEditor)
protected
function FloatInRange(AValue: Extended; AType: TFloatType): Boolean;
public
function AllEqual: Boolean; override;
function FormatValue(const AValue: Extended): ansistring;
@ -3934,6 +3936,44 @@ end;
{ TFloatPropertyEditor }
function TFloatPropertyEditor.FloatInRange(AValue: Extended; AType: TFloatType): Boolean;
{$ifndef FPC_HAS_TYPE_DOUBLE}
const MaxDouble = Math.MaxSingle;
{$endif}
{$ifndef FPC_HAS_TYPE_EXTENDED}
const MaxExtended = MaxDouble;
{$endif}
{$ifndef FPC_HAS_TYPE_COMP}
const
MaxComp = 9223372036854775807;
MinComp = -9223372036854775808;
{$endif}
begin
try
case AType of
ftSingle: Result := {$ifndef FPC_HAS_TYPE_DOUBLE}
//Extended=Single, so anything out of range of a Single will be +/-Infinity
not IsInfinite(AValue);
{$else}
(AValue <= MaxSingle) and (AValue >= -MaxSingle);
{$endif}
ftDouble: Result := {$ifndef FPC_HAS_TYPE_EXTENDED}
//Extended=Double, so anything out of range of a Double will be +/-Infinity
not IsInfinite(AValue);
{$else}
(AValue <= MaxDouble) and (AValue >= -MaxDouble);
{$endif}
ftExtended: Result := not IsInfinite(AValue);
ftComp: Result := (AValue <= MaxComp) and (AValue >= MinComp);
ftCurr: Result := (AValue <= MaxCurrency) and (AValue >= MinCurrency);
end;
except
//Currency comparisons can cause Floating Point overflow on Win64 (i.e. compared with +/-MaxDouble, +/-MaxExtended, MaxComp, MinComp, +/-Inf)
//and on Win32 (i.e with +/-MaxExtended), not tested other platforms
Result := False;
end;
end;
function TFloatPropertyEditor.AllEqual: Boolean;
var
I: Integer;
@ -3977,6 +4017,7 @@ procedure TFloatPropertyEditor.SetValue(const NewValue: ansistring);
var
FS: TFormatSettings;
NewFloat: Extended;
fType: TFloatType;
begin
//writeln('TFloatPropertyEditor.SetValue A ',NewValue,' ',StrToFloat(NewValue));
FS := DefaultFormatSettings;
@ -3984,14 +4025,21 @@ begin
if not TryStrToFloat(NewValue, NewFloat, FS) then
//if this failed, assume the user entered DS from his current locale
NewFloat := StrToFloat(NewValue, DefaultFormatSettings);
if IsInfinite(NewFloat) then
//conversion succeeded, out of range input gets converted to +/-Inf as well, not only literal user input as '+Inf'
//so check user input instead of IsInfinite now
if (Pos('inf',LowerCase(NewValue)) > 0) then
raise EPropertyError.Create(oisInfinityNotSupported);
//Check NaN before checking for range, since you cannot compare NaN to anything
if IsNan(NewFloat) then
raise EPropertyError.Create(oisNaNNotSupported);
fType := GetTypeData(GetPropType)^.FloatType;
if not FloatInRange(NewFloat, fType) then
raise EPropertyError.Create(oisValueOutOfRange);
SetFloatValue(NewFloat);
//writeln('TFloatPropertyEditor.SetValue B ',GetValue);
end;
{ TStringPropertyEditor }
function TStringPropertyEditor.AllEqual: Boolean;