You've already forked lazarus-ccr
fpspreadsheet: Better detection of fraction format by numberformat action. Some clean-up.
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@4145 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@@ -837,21 +837,21 @@ object MainForm: TMainForm
|
||||
WorkbookSource = WorkbookSource
|
||||
Caption = 'Fraction (1 digit)'
|
||||
NumberFormat = nfFraction
|
||||
NumberFormatString = '# #/#'
|
||||
NumberFormatString = '# ?/?'
|
||||
end
|
||||
object AcNumFormatFraction2: TsNumberFormatAction
|
||||
Category = 'FPSpreadsheet'
|
||||
WorkbookSource = WorkbookSource
|
||||
Caption = 'Fraction (2 digits)'
|
||||
NumberFormat = nfFraction
|
||||
NumberFormatString = '# ##/##'
|
||||
NumberFormatString = '# ??/??'
|
||||
end
|
||||
object AcNumFormatFraction3: TsNumberFormatAction
|
||||
Category = 'FPSpreadsheet'
|
||||
WorkbookSource = WorkbookSource
|
||||
Caption = 'Fraction (3 digits)'
|
||||
NumberFormat = nfFraction
|
||||
NumberFormatString = '# ###/###'
|
||||
NumberFormatString = '# ???/???'
|
||||
end
|
||||
object AcNumFormatDateTime: TsNumberFormatAction
|
||||
Category = 'FPSpreadsheet'
|
||||
|
@@ -44,6 +44,71 @@ implementation
|
||||
uses
|
||||
Math, ButtonPanel, fpsUtils;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Concatenates the day names specified in ADayNames to a single string. If all
|
||||
daynames are empty AEmptyStr is returned
|
||||
|
||||
@param ADayNames Array[1..7] of day names as used in the Formatsettings
|
||||
@param AEmptyStr Is returned if all day names are empty
|
||||
@return String having all day names concatenated and separated by the
|
||||
DefaultFormatSettings.ListSeparator
|
||||
-------------------------------------------------------------------------------}
|
||||
function DayNamesToString(const ADayNames: TWeekNameArray;
|
||||
const AEmptyStr: String): String;
|
||||
var
|
||||
i: Integer;
|
||||
isEmpty: Boolean;
|
||||
begin
|
||||
isEmpty := true;
|
||||
for i:=1 to 7 do
|
||||
if ADayNames[i] <> '' then
|
||||
begin
|
||||
isEmpty := false;
|
||||
break;
|
||||
end;
|
||||
|
||||
if isEmpty then
|
||||
Result := AEmptyStr
|
||||
else
|
||||
begin
|
||||
Result := ADayNames[1];
|
||||
for i:=2 to 7 do
|
||||
Result := Result + DefaultFormatSettings.ListSeparator + ' ' + ADayNames[i];
|
||||
end;
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Concatenates the month names specified in AMonthNames to a single string.
|
||||
If all month names are empty AEmptyStr is returned
|
||||
|
||||
@param AMonthNames Array[1..12] of month names as used in the Formatsettings
|
||||
@param AEmptyStr Is returned if all month names are empty
|
||||
@return String having all month names concatenated and separated by the
|
||||
DefaultFormatSettings.ListSeparator
|
||||
-------------------------------------------------------------------------------}
|
||||
function MonthNamesToString(const AMonthNames: TMonthNameArray;
|
||||
const AEmptyStr: String): String;
|
||||
var
|
||||
i: Integer;
|
||||
isEmpty: Boolean;
|
||||
begin
|
||||
isEmpty := true;
|
||||
for i:=1 to 12 do
|
||||
if AMonthNames[i] <> '' then
|
||||
begin
|
||||
isEmpty := false;
|
||||
break;
|
||||
end;
|
||||
|
||||
if isEmpty then
|
||||
Result := AEmptyStr
|
||||
else
|
||||
begin
|
||||
Result := AMonthNames[1];
|
||||
for i:=2 to 12 do
|
||||
Result := Result + DefaultFormatSettings.ListSeparator + ' ' + AMonthNames[i];
|
||||
end;
|
||||
end;
|
||||
|
||||
{ TMonthDayNamesEdit }
|
||||
|
||||
|
@@ -21,11 +21,6 @@
|
||||
{ The next defines activate code duplicated from new compiler versions in case
|
||||
an old compiler is used. }
|
||||
|
||||
{ Numberformats require an extended version of FormatDateTime (in SysUtils)
|
||||
which is not available before FPC 3.0. Define FPS_FORMATDATETIME if the
|
||||
compiler used is older. }
|
||||
{$DEFINE FPS_FORMATDATETIME}
|
||||
|
||||
{ fpspreadsheet requires the function VarIsBool which was introduced by
|
||||
fpc 2.6.4. If an older FPC versions is used define FPS_VARISBOOL. Keep
|
||||
undefined for the current FPC version. }
|
||||
|
@@ -305,10 +305,14 @@ begin
|
||||
section := @FSections[ASection];
|
||||
section^.Kind := [];
|
||||
|
||||
i := 0;
|
||||
|
||||
for el := 0 to High(section^.Elements) do
|
||||
case section^.Elements[el].Token of
|
||||
nftZeroDecs:
|
||||
section^.Decimals := section^.Elements[el].IntValue;
|
||||
nftIntZeroDigit, nftIntOptDigit, nftIntSpaceDigit:
|
||||
i := section^.Elements[el].IntValue;
|
||||
nftFracNumSpaceDigit, nftFracNumZeroDigit:
|
||||
section^.FracNumerator := section^.Elements[el].IntValue;
|
||||
nftFracDenomSpaceDigit, nftFracDenomZeroDigit:
|
||||
@@ -331,7 +335,10 @@ begin
|
||||
if (nfkFraction in section^.Kind) then
|
||||
FStatus := psErrMultipleFracSymbols
|
||||
else
|
||||
begin
|
||||
section^.Kind := section^.Kind + [nfkFraction];
|
||||
section^.FracInt := i;
|
||||
end;
|
||||
nftCurrSymbol:
|
||||
begin
|
||||
if (nfkCurrency in section^.Kind) then
|
||||
@@ -405,7 +412,12 @@ begin
|
||||
end else
|
||||
begin
|
||||
nfs := GetFormatString;
|
||||
formats := [nfFixed, nfFixedTh, nfPercentage, nfExp, nfFraction];
|
||||
nfsTest := BuildFractionFormatString(section^.FracInt > 0, section^.FracNumerator, section^.FracDenominator);
|
||||
if sameText(nfs, nfsTest) then
|
||||
section^.NumFormat := nfFraction
|
||||
else
|
||||
begin
|
||||
formats := [nfFixed, nfFixedTh, nfPercentage, nfExp];
|
||||
for nf in formats do begin
|
||||
nfsTest := BuildNumberFormatString(nf, FWorkbook.FormatSettings, section^.Decimals);
|
||||
if SameText(nfs, nfsTest) then
|
||||
@@ -414,6 +426,7 @@ begin
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
if (section^.NumFormat = nfCustom) and (nfkCurrency in section^.Kind) then
|
||||
begin
|
||||
section^.NumFormat := nfCurrency;
|
||||
|
@@ -230,7 +230,7 @@ implementation
|
||||
|
||||
uses
|
||||
StrUtils, Variants, LazFileUtils, URIParser,
|
||||
fpsPatches, fpsStrings, fpsStreams, fpsExprParser;
|
||||
fpsStrings, fpsStreams, fpsExprParser;
|
||||
|
||||
const
|
||||
{ OpenDocument general XML constants }
|
||||
@@ -5364,6 +5364,7 @@ var
|
||||
r1,c1,r2,c2: Cardinal;
|
||||
fmt: TsCellFormat;
|
||||
numFmtParams: TsNumFormatParams;
|
||||
h,m,s,ms: Word;
|
||||
begin
|
||||
Unused(ARow, ACol);
|
||||
|
||||
@@ -5395,7 +5396,9 @@ begin
|
||||
|
||||
if IsTimeIntervalformat(numFmtParams) then
|
||||
begin
|
||||
strValue := FormatDateTime(ISO8601FormatHoursOverflow, AValue, [fdoInterval]);
|
||||
DecodeTime(AValue, h,m,s,ms);
|
||||
strValue := Format('PT%02dH%02dM%02d.%03dS', [trunc(AValue)*24+h, m, s, ms]);
|
||||
// strValue := FormatDateTime(ISO8601FormatHoursOverflow, AValue, [fdoInterval]);
|
||||
displayStr := FWorksheet.ReadAsUTF8Text(ACell);
|
||||
// displayStr := FormatDateTime(fmt.NumberFormatStr, AValue, [fdoInterval]);
|
||||
AppendToStream(AStream, Format(
|
||||
|
@@ -16,13 +16,13 @@ uses
|
||||
Classes, SysUtils;
|
||||
|
||||
{$IFDEF FPS_VARISBOOL}
|
||||
{ Needed only if FPC version is < 2.6.4 }
|
||||
{ Needed only if FPC version is < 2.6.4 }
|
||||
function VarIsBool(const V: Variant): Boolean;
|
||||
{$ENDIF}
|
||||
|
||||
|
||||
{$IFDEF FPS_LAZUTF8}
|
||||
// implemented in LazUTF8 in r43348 (Laz 1.2)
|
||||
// implemented in LazUTF8 of r43348 (Laz 1.2)
|
||||
function UTF8LeftStr(const AText: String; const ACount: Integer): String;
|
||||
function UTF8RightStr(const AText: String; const ACount: Integer): String;
|
||||
function UTF8StringReplace(const S, OldPattern, NewPattern: String;
|
||||
@@ -32,19 +32,6 @@ uses
|
||||
{$ENDIF}
|
||||
|
||||
|
||||
{$IFDEF FPS_FORMATDATETIME}
|
||||
type
|
||||
TFormatDateTimeOption = (fdoInterval);
|
||||
TFormatDateTimeOptions = set of TFormatDateTimeOption;
|
||||
|
||||
// Needed if fpc version is < 3.0.
|
||||
function FormatDateTime(const FormatStr: string; DateTime: TDateTime;
|
||||
Options : TFormatDateTimeOptions = []): string;
|
||||
function FormatDateTime(const FormatStr: string; DateTime: TDateTime;
|
||||
const FormatSettings: TFormatSettings; Options : TFormatDateTimeOptions = []): string;
|
||||
{$ENDIF}
|
||||
|
||||
|
||||
implementation
|
||||
|
||||
{$IFDEF FPS_VARISBOOL}
|
||||
@@ -1706,325 +1693,6 @@ begin
|
||||
// Final correction of the buffer size
|
||||
SetLength(Result,OutCounter);
|
||||
end;
|
||||
|
||||
{$ENDIF}
|
||||
|
||||
|
||||
{$IFDEF FPS_FORMATDATETIME}
|
||||
{******************************************************************************}
|
||||
{******************************************************************************}
|
||||
{ Patch for SysUtils.FormatDateTime }
|
||||
{******************************************************************************}
|
||||
{******************************************************************************}
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Applies a formatting string to a date/time value and converts the number
|
||||
to a date/time string.
|
||||
|
||||
This functionality is available in the SysUtils unit. But it is duplicated
|
||||
here to add a patch which is not available in stable fpc.
|
||||
-------------------------------------------------------------------------------}
|
||||
procedure DateTimeToString(out Result: string; const FormatStr: string; const DateTime: TDateTime;
|
||||
const FormatSettings: TFormatSettings; Options : TFormatDateTimeOptions = []);
|
||||
// Copied from "fpc/rtl/objpas/sysutils/datei.inc"
|
||||
var
|
||||
ResultLen: integer;
|
||||
ResultBuffer: array[0..255] of char;
|
||||
ResultCurrent: pchar;
|
||||
|
||||
procedure StoreStr(Str: PChar; Len: Integer);
|
||||
begin
|
||||
if ResultLen + Len < SizeOf(ResultBuffer) then
|
||||
begin
|
||||
StrMove(ResultCurrent, Str, Len);
|
||||
ResultCurrent := ResultCurrent + Len;
|
||||
ResultLen := ResultLen + Len;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure StoreString(const Str: string);
|
||||
var Len: integer;
|
||||
begin
|
||||
Len := Length(Str);
|
||||
if ResultLen + Len < SizeOf(ResultBuffer) then
|
||||
begin
|
||||
StrMove(ResultCurrent, pchar(Str), Len);
|
||||
ResultCurrent := ResultCurrent + Len;
|
||||
ResultLen := ResultLen + Len;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure StoreInt(Value, Digits: Integer);
|
||||
var
|
||||
S: string[16];
|
||||
Len: integer;
|
||||
begin
|
||||
System.Str(Value:Digits, S);
|
||||
for Len := 1 to Length(S) do
|
||||
begin
|
||||
if S[Len] = ' ' then
|
||||
S[Len] := '0'
|
||||
else
|
||||
Break;
|
||||
end;
|
||||
StoreStr(pchar(@S[1]), Length(S));
|
||||
end ;
|
||||
|
||||
var
|
||||
Year, Month, Day, DayOfWeek, Hour, Minute, Second, MilliSecond: word;
|
||||
|
||||
procedure StoreFormat(const FormatStr: string; Nesting: Integer; TimeFlag: Boolean);
|
||||
var
|
||||
Token, lastformattoken, prevlasttoken: char;
|
||||
FormatCurrent: pchar;
|
||||
FormatEnd: pchar;
|
||||
Count: integer;
|
||||
Clock12: boolean;
|
||||
P: pchar;
|
||||
tmp: integer;
|
||||
isInterval: Boolean;
|
||||
|
||||
begin
|
||||
if Nesting > 1 then // 0 is original string, 1 is included FormatString
|
||||
Exit;
|
||||
|
||||
FormatCurrent := PChar(FormatStr);
|
||||
FormatEnd := FormatCurrent + Length(FormatStr);
|
||||
Clock12 := false;
|
||||
isInterval := false;
|
||||
P := FormatCurrent;
|
||||
// look for unquoted 12-hour clock token
|
||||
while P < FormatEnd do
|
||||
begin
|
||||
Token := P^;
|
||||
case Token of
|
||||
'''', '"':
|
||||
begin
|
||||
Inc(P);
|
||||
while (P < FormatEnd) and (P^ <> Token) do
|
||||
Inc(P);
|
||||
end;
|
||||
'A', 'a':
|
||||
begin
|
||||
if (StrLIComp(P, 'A/P', 3) = 0) or
|
||||
(StrLIComp(P, 'AMPM', 4) = 0) or
|
||||
(StrLIComp(P, 'AM/PM', 5) = 0) then
|
||||
begin
|
||||
Clock12 := true;
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
end; // case
|
||||
Inc(P);
|
||||
end ;
|
||||
token := #255;
|
||||
lastformattoken := ' ';
|
||||
prevlasttoken := 'H';
|
||||
while FormatCurrent < FormatEnd do
|
||||
begin
|
||||
Token := UpCase(FormatCurrent^);
|
||||
Count := 1;
|
||||
P := FormatCurrent + 1;
|
||||
case Token of
|
||||
'''', '"':
|
||||
begin
|
||||
while (P < FormatEnd) and (p^ <> Token) do
|
||||
Inc(P);
|
||||
Inc(P);
|
||||
Count := P - FormatCurrent;
|
||||
StoreStr(FormatCurrent + 1, Count - 2);
|
||||
end ;
|
||||
'A':
|
||||
begin
|
||||
if StrLIComp(FormatCurrent, 'AMPM', 4) = 0 then
|
||||
begin
|
||||
Count := 4;
|
||||
if Hour < 12 then
|
||||
StoreString(FormatSettings.TimeAMString)
|
||||
else
|
||||
StoreString(FormatSettings.TimePMString);
|
||||
end
|
||||
else if StrLIComp(FormatCurrent, 'AM/PM', 5) = 0 then
|
||||
begin
|
||||
Count := 5;
|
||||
if Hour < 12 then StoreStr(FormatCurrent, 2)
|
||||
else StoreStr(FormatCurrent+3, 2);
|
||||
end
|
||||
else if StrLIComp(FormatCurrent, 'A/P', 3) = 0 then
|
||||
begin
|
||||
Count := 3;
|
||||
if Hour < 12 then StoreStr(FormatCurrent, 1)
|
||||
else StoreStr(FormatCurrent+2, 1);
|
||||
end
|
||||
else
|
||||
raise EConvertError.Create('Illegal character in format string');
|
||||
end ;
|
||||
'/': StoreStr(@FormatSettings.DateSeparator, 1);
|
||||
':': StoreStr(@FormatSettings.TimeSeparator, 1);
|
||||
'[': if (fdoInterval in Options) then isInterval := true else StoreStr(FormatCurrent, 1);
|
||||
']': if (fdoInterval in Options) then isInterval := false else StoreStr(FormatCurrent, 1);
|
||||
' ', 'C', 'D', 'H', 'M', 'N', 'S', 'T', 'Y', 'Z', 'F' :
|
||||
begin
|
||||
while (P < FormatEnd) and (UpCase(P^) = Token) do
|
||||
Inc(P);
|
||||
Count := P - FormatCurrent;
|
||||
case Token of
|
||||
' ': StoreStr(FormatCurrent, Count);
|
||||
'Y': begin
|
||||
if Count > 2 then
|
||||
StoreInt(Year, 4)
|
||||
else
|
||||
StoreInt(Year mod 100, 2);
|
||||
end;
|
||||
'M': begin
|
||||
if isInterval and ((prevlasttoken = 'H') or TimeFlag) then
|
||||
StoreInt(Minute + (Hour + trunc(abs(DateTime))*24)*60, 0)
|
||||
else
|
||||
if (lastformattoken = 'H') or TimeFlag then
|
||||
begin
|
||||
if Count = 1 then
|
||||
StoreInt(Minute, 0)
|
||||
else
|
||||
StoreInt(Minute, 2);
|
||||
end
|
||||
else
|
||||
begin
|
||||
case Count of
|
||||
1: StoreInt(Month, 0);
|
||||
2: StoreInt(Month, 2);
|
||||
3: StoreString(FormatSettings.ShortMonthNames[Month]);
|
||||
else
|
||||
StoreString(FormatSettings.LongMonthNames[Month]);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
'D': begin
|
||||
case Count of
|
||||
1: StoreInt(Day, 0);
|
||||
2: StoreInt(Day, 2);
|
||||
3: StoreString(FormatSettings.ShortDayNames[DayOfWeek]);
|
||||
4: StoreString(FormatSettings.LongDayNames[DayOfWeek]);
|
||||
5: StoreFormat(FormatSettings.ShortDateFormat, Nesting+1, False);
|
||||
else
|
||||
StoreFormat(FormatSettings.LongDateFormat, Nesting+1, False);
|
||||
end ;
|
||||
end ;
|
||||
'H':
|
||||
if isInterval then
|
||||
StoreInt(Hour + trunc(abs(DateTime))*24, 0)
|
||||
else
|
||||
if Clock12 then
|
||||
begin
|
||||
tmp := hour mod 12;
|
||||
if tmp=0 then tmp:=12;
|
||||
if Count = 1 then
|
||||
StoreInt(tmp, 0)
|
||||
else
|
||||
StoreInt(tmp, 2);
|
||||
end
|
||||
else begin
|
||||
if Count = 1 then
|
||||
StoreInt(Hour, 0)
|
||||
else
|
||||
StoreInt(Hour, 2);
|
||||
end;
|
||||
'N': if isInterval then
|
||||
StoreInt(Minute + (Hour + trunc(abs(DateTime))*24)*60, 0)
|
||||
else
|
||||
if Count = 1 then
|
||||
StoreInt(Minute, 0)
|
||||
else
|
||||
StoreInt(Minute, 2);
|
||||
'S': if isInterval then
|
||||
StoreInt(Second + (Minute + (Hour + trunc(abs(DateTime))*24)*60)*60, 0)
|
||||
else
|
||||
if Count = 1 then
|
||||
StoreInt(Second, 0)
|
||||
else
|
||||
StoreInt(Second, 2);
|
||||
'Z': if Count = 1 then
|
||||
StoreInt(MilliSecond, 0)
|
||||
else
|
||||
StoreInt(MilliSecond, 3);
|
||||
'T': if Count = 1 then
|
||||
StoreFormat(FormatSettings.ShortTimeFormat, Nesting+1, True)
|
||||
else
|
||||
StoreFormat(FormatSettings.LongTimeFormat, Nesting+1, True);
|
||||
'C': begin
|
||||
StoreFormat(FormatSettings.ShortDateFormat, Nesting+1, False);
|
||||
if (Hour<>0) or (Minute<>0) or (Second<>0) then
|
||||
begin
|
||||
StoreString(' ');
|
||||
StoreFormat(FormatSettings.LongTimeFormat, Nesting+1, True);
|
||||
end;
|
||||
end;
|
||||
'F': begin
|
||||
StoreFormat(FormatSettings.ShortDateFormat, Nesting+1, False);
|
||||
StoreString(' ');
|
||||
StoreFormat(FormatSettings.LongTimeFormat, Nesting+1, True);
|
||||
end;
|
||||
end;
|
||||
prevlasttoken := lastformattoken;
|
||||
lastformattoken := token;
|
||||
end;
|
||||
else
|
||||
StoreStr(@Token, 1);
|
||||
end ;
|
||||
Inc(FormatCurrent, Count);
|
||||
end;
|
||||
end;
|
||||
|
||||
begin
|
||||
DecodeDateFully(DateTime, Year, Month, Day, DayOfWeek);
|
||||
DecodeTime(DateTime, Hour, Minute, Second, MilliSecond);
|
||||
ResultLen := 0;
|
||||
ResultCurrent := @ResultBuffer[0];
|
||||
if FormatStr <> '' then
|
||||
StoreFormat(FormatStr, 0, False)
|
||||
else
|
||||
StoreFormat('C', 0, False);
|
||||
ResultBuffer[ResultLen] := #0;
|
||||
result := StrPas(@ResultBuffer[0]);
|
||||
end ;
|
||||
|
||||
{@@
|
||||
Applies a formatting string to a date/time value and converts the number
|
||||
to a date/time string.
|
||||
|
||||
This functionality is available in the SysUtils unit. But it is duplicated
|
||||
here to add a patch which is not available in stable fpc.
|
||||
}
|
||||
procedure DateTimeToString(out Result: string; const FormatStr: string;
|
||||
const DateTime: TDateTime; Options : TFormatDateTimeOptions = []);
|
||||
begin
|
||||
DateTimeToString(Result, FormatStr, DateTime, DefaultFormatSettings, Options);
|
||||
end;
|
||||
|
||||
{@@
|
||||
Applies a formatting string to a date/time value and converts the number
|
||||
to a date/time string.
|
||||
|
||||
This functionality is available in the SysUtils unit. But it is duplicated
|
||||
here to add a patch which is not available in stable fpc.
|
||||
}
|
||||
function FormatDateTime(const FormatStr: string; DateTime: TDateTime;
|
||||
Options : TFormatDateTimeOptions = []): string;
|
||||
begin
|
||||
DateTimeToString(Result, FormatStr, DateTime, DefaultFormatSettings,Options);
|
||||
end;
|
||||
|
||||
{@@
|
||||
Applies a formatting string to a date/time value and converts the number
|
||||
to a date/time string.
|
||||
|
||||
This functionality is available in the SysUtils unit. But it is duplicated
|
||||
here to add a patch which is not available in stable fpc.
|
||||
}
|
||||
function FormatDateTime(const FormatStr: string; DateTime: TDateTime;
|
||||
const FormatSettings: TFormatSettings; Options : TFormatDateTimeOptions = []): string;
|
||||
begin
|
||||
DateTimeToString(Result, FormatStr, DateTime, FormatSettings,Options);
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
end.
|
||||
|
@@ -792,7 +792,7 @@ implementation
|
||||
|
||||
uses
|
||||
Math, StrUtils, DateUtils, TypInfo, lazutf8, lazFileUtils, URIParser,
|
||||
fpsPatches, fpsStrings, uvirtuallayer_ole,
|
||||
fpsStrings, uvirtuallayer_ole,
|
||||
fpsUtils, fpsreaderwriter, fpsCurrency, fpsExprParser,
|
||||
fpsNumFormat, fpsNumFormatParser;
|
||||
|
||||
@@ -3976,6 +3976,7 @@ var
|
||||
fmt: TsCellFormat;
|
||||
numFmtParams: TsNumFormatParams;
|
||||
maxDig: Integer;
|
||||
isMixed: Boolean;
|
||||
begin
|
||||
if ACell = nil then
|
||||
exit;
|
||||
@@ -3998,10 +3999,10 @@ begin
|
||||
exit;
|
||||
end;
|
||||
|
||||
if TryFractionStrToFloat(AValue, number, maxdig) then
|
||||
if TryFractionStrToFloat(AValue, number, ismixed, maxdig) then
|
||||
begin
|
||||
WriteNumber(ACell, number);
|
||||
WriteFractionFormat(ACell, true, maxdig, maxdig);
|
||||
WriteFractionFormat(ACell, ismixed, maxdig, maxdig);
|
||||
exit;
|
||||
end;
|
||||
|
||||
|
@@ -111,18 +111,10 @@ function AddAMPM(const ATimeFormatString: String;
|
||||
function StripAMPM(const ATimeFormatString: String): String;
|
||||
function CountDecs(AFormatString: String; ADecChars: TsDecsChars = ['0']): Byte;
|
||||
function AddIntervalBrackets(AFormatString: String): String;
|
||||
function DayNamesToString(const ADayNames: TWeekNameArray;
|
||||
const AEmptyStr: String): String;
|
||||
function MakeLongDateFormat(ADateFormat: String): String;
|
||||
function MakeShortDateFormat(ADateFormat: String): String;
|
||||
function MonthNamesToString(const AMonthNames: TMonthNameArray;
|
||||
const AEmptyStr: String): String;
|
||||
function SpecialDateTimeFormat(ACode: String;
|
||||
const AFormatSettings: TFormatSettings; ForWriting: Boolean): String;
|
||||
{
|
||||
procedure SplitFormatString(const AFormatString: String; out APositivePart,
|
||||
ANegativePart, AZeroPart: String);
|
||||
}
|
||||
procedure MakeTimeIntervalMask(Src: String; var Dest: String);
|
||||
|
||||
function ConvertFloatToStr(AValue: Double; AParams: TsNumFormatParams;
|
||||
@@ -132,7 +124,7 @@ procedure FloatToFraction(AValue: Double; AMaxDenominator: Int64;
|
||||
function TryStrToFloatAuto(AText: String; out ANumber: Double;
|
||||
out ADecimalSeparator, AThousandSeparator: Char; out AWarning: String): Boolean;
|
||||
function TryFractionStrToFloat(AText: String; out ANumber: Double;
|
||||
out AMaxDigits: Integer): Boolean;
|
||||
out AIsMixed: Boolean; out AMaxDigits: Integer): Boolean;
|
||||
|
||||
function TwipsToPts(AValue: Integer): Single; inline;
|
||||
function PtsToTwips(AValue: Single): Integer; inline;
|
||||
@@ -1347,39 +1339,6 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Concatenates the day names specified in ADayNames to a single string. If all
|
||||
daynames are empty AEmptyStr is returned
|
||||
|
||||
@param ADayNames Array[1..7] of day names as used in the Formatsettings
|
||||
@param AEmptyStr Is returned if all day names are empty
|
||||
@return String having all day names concatenated and separated by the
|
||||
DefaultFormatSettings.ListSeparator
|
||||
-------------------------------------------------------------------------------}
|
||||
function DayNamesToString(const ADayNames: TWeekNameArray;
|
||||
const AEmptyStr: String): String;
|
||||
var
|
||||
i: Integer;
|
||||
isEmpty: Boolean;
|
||||
begin
|
||||
isEmpty := true;
|
||||
for i:=1 to 7 do
|
||||
if ADayNames[i] <> '' then
|
||||
begin
|
||||
isEmpty := false;
|
||||
break;
|
||||
end;
|
||||
|
||||
if isEmpty then
|
||||
Result := AEmptyStr
|
||||
else
|
||||
begin
|
||||
Result := ADayNames[1];
|
||||
for i:=2 to 7 do
|
||||
Result := Result + DefaultFormatSettings.ListSeparator + ' ' + ADayNames[i];
|
||||
end;
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Approximates a floating point value as a fraction and returns the values of
|
||||
numerator and denominator.
|
||||
@@ -1532,39 +1491,6 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Concatenates the month names specified in AMonthNames to a single string.
|
||||
If all month names are empty AEmptyStr is returned
|
||||
|
||||
@param AMonthNames Array[1..12] of month names as used in the Formatsettings
|
||||
@param AEmptyStr Is returned if all month names are empty
|
||||
@return String having all month names concatenated and separated by the
|
||||
DefaultFormatSettings.ListSeparator
|
||||
-------------------------------------------------------------------------------}
|
||||
function MonthNamesToString(const AMonthNames: TMonthNameArray;
|
||||
const AEmptyStr: String): String;
|
||||
var
|
||||
i: Integer;
|
||||
isEmpty: Boolean;
|
||||
begin
|
||||
isEmpty := true;
|
||||
for i:=1 to 12 do
|
||||
if AMonthNames[i] <> '' then
|
||||
begin
|
||||
isEmpty := false;
|
||||
break;
|
||||
end;
|
||||
|
||||
if isEmpty then
|
||||
Result := AEmptyStr
|
||||
else
|
||||
begin
|
||||
Result := AMonthNames[1];
|
||||
for i:=2 to 12 do
|
||||
Result := Result + DefaultFormatSettings.ListSeparator + ' ' + AMonthNames[i];
|
||||
end;
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Creates the formatstrings for the date/time codes "dm", "my", "ms" and "msz"
|
||||
out of the formatsettings.
|
||||
@@ -1610,81 +1536,6 @@ begin
|
||||
Result := ACode;
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Currency formatting strings consist of three parts, separated by
|
||||
semicolons, which are valid for positive, negative or zero values.
|
||||
Splits such a formatting string at the positions of the semicolons and
|
||||
returns the sections. If semicolons are used for other purposed within
|
||||
sections they have to be quoted by " or escaped by \. If the formatting
|
||||
string contains less sections than three the missing strings are returned
|
||||
as empty strings.
|
||||
|
||||
@param AFormatString String of number formatting codes.
|
||||
@param APositivePart First section of the formatting string which is valid
|
||||
for positive numbers (or positive and zero, if there
|
||||
are only two sections)
|
||||
@param ANegativePart Second section of the formatting string which is valid
|
||||
for negative numbers
|
||||
@param AZeroPart Third section of the formatting string for zero.
|
||||
-------------------------------------------------------------------------------}
|
||||
(*
|
||||
procedure SplitFormatString(const AFormatString: String; out APositivePart,
|
||||
ANegativePart, AZeroPart: String);
|
||||
|
||||
procedure AddToken(AToken: Char; AWhere:Byte);
|
||||
begin
|
||||
case AWhere of
|
||||
0: APositivePart := APositivePart + AToken;
|
||||
1: ANegativePart := ANegativePart + AToken;
|
||||
2: AZeroPart := AZeroPart + AToken;
|
||||
end;
|
||||
end;
|
||||
|
||||
var
|
||||
P, PStart, PEnd: PChar;
|
||||
token: Char;
|
||||
where: Byte; // 0 = positive part, 1 = negative part, 2 = zero part
|
||||
begin
|
||||
APositivePart := '';
|
||||
ANegativePart := '';
|
||||
AZeroPart := '';
|
||||
if AFormatString = '' then
|
||||
exit;
|
||||
|
||||
PStart := PChar(@AFormatString[1]);
|
||||
PEnd := PStart + Length(AFormatString);
|
||||
P := PStart;
|
||||
where := 0;
|
||||
while P < PEnd do begin
|
||||
token := P^;
|
||||
case token of
|
||||
'"': begin // Let quoted text intact
|
||||
AddToken(token, where);
|
||||
inc(P);
|
||||
token := P^;
|
||||
while (P < PEnd) and (token <> '"') do begin
|
||||
AddToken(token, where);
|
||||
inc(P);
|
||||
token := P^;
|
||||
end;
|
||||
AddToken(token, where);
|
||||
end;
|
||||
';': begin // Separator between parts
|
||||
inc(where);
|
||||
if where = 3 then
|
||||
exit;
|
||||
end;
|
||||
'\': begin // Skip "Escape" character and add next char immediately
|
||||
inc(P);
|
||||
token := P^;
|
||||
AddToken(token, where);
|
||||
end;
|
||||
else AddToken(token, where);
|
||||
end;
|
||||
inc(P);
|
||||
end;
|
||||
end;
|
||||
*)
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Creates a "time interval" format string having the first time code identifier
|
||||
in square brackets.
|
||||
@@ -1894,7 +1745,7 @@ end;
|
||||
@example AText := '1 3/4' --> ANumber = 1.75; AMaxDigits = 1; Result = true
|
||||
-------------------------------------------------------------------------------}
|
||||
function TryFractionStrToFloat(AText: String; out ANumber: Double;
|
||||
out AMaxDigits: Integer): Boolean;
|
||||
out AIsMixed: Boolean; out AMaxDigits: Integer): Boolean;
|
||||
var
|
||||
p: Integer;
|
||||
s, sInt, sNum, sDenom: String;
|
||||
@@ -1931,6 +1782,7 @@ begin
|
||||
if sInt <> '' then
|
||||
ANumber := ANumber + i;
|
||||
|
||||
AIsMixed := (sInt <> '');
|
||||
AMaxDigits := Length(sDenom);
|
||||
|
||||
Result := true;
|
||||
|
@@ -27,10 +27,10 @@ var
|
||||
SollNumberFormats: array[0..9] of TsNumberFormat;
|
||||
SollNumberDecimals: array[0..9] of word;
|
||||
|
||||
SollDateTimeStrings: array[0..4, 0..9] of string;
|
||||
SollDateTimeStrings: array[0..4, 0..8] of string;
|
||||
SollDateTimes: array[0..4] of TDateTime;
|
||||
SollDateTimeFormats: array[0..9] of TsNumberFormat;
|
||||
SollDateTimeFormatStrings: array[0..9] of String;
|
||||
SollDateTimeFormats: array[0..8] of TsNumberFormat;
|
||||
SollDateTimeFormatStrings: array[0..8] of String;
|
||||
|
||||
SollColWidths: array[0..1] of Single;
|
||||
SollRowHeights: Array[0..2] of Single;
|
||||
@@ -256,7 +256,7 @@ begin
|
||||
SollDateTimeFormats[6] := nfCustom; SollDateTimeFormatStrings[6] := 'dd/mmm';
|
||||
SolLDateTimeFormats[7] := nfCustom; SollDateTimeFormatStrings[7] := 'mmm/yy';
|
||||
SollDateTimeFormats[8] := nfCustom; SollDateTimeFormatStrings[8] := 'nn:ss';
|
||||
SollDateTimeFormats[9] := nfTimeInterval; SollDateTimeFormatStrings[9] := '';
|
||||
// SollDateTimeFormats[9] := nfTimeInterval; SollDateTimeFormatStrings[9] := '';
|
||||
|
||||
for i:=Low(SollDateTimes) to High(SollDateTimes) do
|
||||
begin
|
||||
@@ -269,7 +269,7 @@ begin
|
||||
SollDateTimeStrings[i, 6] := FormatDateTime(SpecialDateTimeFormat('dm', fs, false), SollDateTimes[i], fs);
|
||||
SollDateTimeStrings[i, 7] := FormatDateTime(SpecialDateTimeFormat('my', fs, false), SollDateTimes[i], fs);
|
||||
SollDateTimeStrings[i, 8] := FormatDateTime(SpecialDateTimeFormat('ms', fs, false), SollDateTimes[i], fs);
|
||||
SollDateTimeStrings[i, 9] := FormatDateTime('[h]:mm:ss', SollDateTimes[i], fs, [fdoInterval]);
|
||||
// SollDateTimeStrings[i, 9] := FormatDateTime('[h]:mm:ss', SollDateTimes[i], fs, [fdoInterval]);
|
||||
end;
|
||||
|
||||
// Column width
|
||||
|
Reference in New Issue
Block a user