fpspreadsheet: Move TsCellFormatList from fpsTypes.pas to fpsClasses.pas. Updated chm help file after proof-reading.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@4173 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2015-06-01 19:58:26 +00:00
parent 694c87f585
commit 0d7bdfa06c
8 changed files with 263 additions and 300 deletions

View File

@ -173,6 +173,25 @@ type
function GetEnumerator: TsCellRangeEnumerator; function GetEnumerator: TsCellRangeEnumerator;
end; end;
{ TsCellFormatList }
TsCellFormatList = class(TFPList)
private
FAllowDuplicates: Boolean;
function GetItem(AIndex: Integer): PsCellFormat;
procedure SetItem(AIndex: Integer; const AValue: PsCellFormat);
public
constructor Create(AAllowDuplicates: Boolean);
destructor Destroy; override;
function Add(const AItem: TsCellFormat): Integer; overload;
function Add(AItem: PsCellFormat): Integer; overload;
procedure Clear;
procedure Delete(AIndex: Integer);
function FindIndexOfID(ID: Integer): Integer;
function FindIndexOfName(AName: String): Integer;
function IndexOf(const AItem: TsCellFormat): Integer; overload;
property Items[AIndex: Integer]: PsCellFormat read GetItem write SetItem; default;
end;
implementation implementation
@ -1105,5 +1124,176 @@ begin
Result := range; Result := range;
end; end;
{******************************************************************************}
{ TsCellFormatList }
{******************************************************************************}
constructor TsCellFormatList.Create(AAllowDuplicates: Boolean);
begin
inherited Create;
FAllowDuplicates := AAllowDuplicates;
end;
destructor TsCellFormatList.Destroy;
begin
Clear;
inherited;
end;
function TsCellFormatList.Add(const AItem: TsCellFormat): Integer;
var
P: PsCellFormat;
begin
if FAllowDuplicates then
Result := -1
else
Result := IndexOf(AItem);
if Result = -1 then begin
New(P);
P^.Name := AItem.Name;
P^.ID := AItem.ID;
P^.UsedFormattingFields := AItem.UsedFormattingFields;
P^.FontIndex := AItem.FontIndex;
P^.TextRotation := AItem.TextRotation;
P^.HorAlignment := AItem.HorAlignment;
P^.VertAlignment := AItem.VertAlignment;
P^.Border := AItem.Border;
P^.BorderStyles := AItem.BorderStyles;
P^.Background := AItem.Background;
P^.NumberFormatIndex := AItem.NumberFormatIndex;
P^.NumberFormat := AItem.NumberFormat;
P^.NumberFormatStr := AItem.NumberFormatStr;
Result := inherited Add(P);
end;
end;
{@@ ----------------------------------------------------------------------------
Adds a pointer to a FormatRecord to the list. Allows nil for the predefined
formats which are not stored in the file.
-------------------------------------------------------------------------------}
function TsCellFormatList.Add(AItem: PsCellFormat): Integer;
begin
if AItem = nil then
Result := inherited Add(AItem)
else
Result := Add(AItem^);
end;
procedure TsCellFormatList.Clear;
var
i: Integer;
begin
for i:=Count-1 downto 0 do
Delete(i);
inherited;
end;
procedure TsCellFormatList.Delete(AIndex: Integer);
var
P: PsCellFormat;
begin
P := GetItem(AIndex);
if P <> nil then
Dispose(P);
inherited Delete(AIndex);
end;
function TsCellFormatList.GetItem(AIndex: Integer): PsCellFormat;
begin
Result := inherited Items[AIndex];
end;
function TsCellFormatList.FindIndexOfID(ID: Integer): Integer;
var
P: PsCellFormat;
begin
for Result := 0 to Count-1 do
begin
P := GetItem(Result);
if (P <> nil) and (P^.ID = ID) then
exit;
end;
Result := -1;
end;
function TsCellFormatList.FindIndexOfName(AName: String): Integer;
var
P: PsCellFormat;
begin
for Result := 0 to Count-1 do
begin
P := GetItem(Result);
if (P <> nil) and (P^.Name = AName) then
exit;
end;
Result := -1;
end;
function TsCellFormatList.IndexOf(const AItem: TsCellFormat): Integer;
var
P: PsCellFormat;
equ: Boolean;
b: TsCellBorder;
begin
for Result := 0 to Count-1 do
begin
P := GetItem(Result);
if (P = nil) then continue;
if (P^.UsedFormattingFields <> AItem.UsedFormattingFields) then continue;
if (uffFont in AItem.UsedFormattingFields) then
if (P^.FontIndex) <> (AItem.FontIndex) then continue;
if (uffTextRotation in AItem.UsedFormattingFields) then
if (P^.TextRotation <> AItem.TextRotation) then continue;
if (uffHorAlign in AItem.UsedFormattingFields) then
if (P^.HorAlignment <> AItem.HorAlignment) then continue;
if (uffVertAlign in AItem.UsedFormattingFields) then
if (P^.VertAlignment <> AItem.VertAlignment) then continue;
if (uffBorder in AItem.UsedFormattingFields) then
if (P^.Border <> AItem.Border) then continue;
// Border styles can be set even if borders are not used --> don't check uffBorder!
equ := true;
for b in AItem.Border do begin
if (P^.BorderStyles[b].LineStyle <> AItem.BorderStyles[b].LineStyle) or
(P^.BorderStyles[b].Color <> Aitem.BorderStyles[b].Color)
then begin
equ := false;
break;
end;
end;
if not equ then continue;
if (uffBackground in AItem.UsedFormattingFields) then begin
if (P^.Background.Style <> AItem.Background.Style) then continue;
if (P^.Background.BgColor <> AItem.Background.BgColor) then continue;
if (P^.Background.FgColor <> AItem.Background.FgColor) then continue;
end;
if (uffNumberFormat in AItem.UsedFormattingFields) then begin
if (P^.NumberFormatIndex <> AItem.NumberFormatIndex) then continue;
if (P^.NumberFormat <> AItem.NumberFormat) then continue;
if (P^.NumberFormatStr <> AItem.NumberFormatStr) then continue;
end;
// If we arrive here then the format records match.
exit;
end;
// We get here if no record matches
Result := -1;
end;
procedure TsCellFormatList.SetItem(AIndex: Integer; const AValue: PsCellFormat);
begin
inherited Items[AIndex] := AValue;
end;
end. end.

View File

@ -58,7 +58,7 @@ type
nftFracDenomSpaceDigit,// '?' in denominator, count stored in IntValue nftFracDenomSpaceDigit,// '?' in denominator, count stored in IntValue
nftFracDenomZeroDigit, // '0' in denominator, count stored in IntValue nftFracDenomZeroDigit, // '0' in denominator, count stored in IntValue
nftFracDenom, // specified denominator, value stored in IntValue nftFracDenom, // specified denominator, value stored in IntValue
nftCurrSymbol, // e.g., '"$"', stored in TextValue nftCurrSymbol, // e.g., '"€"' or '[$€]', stored in TextValue
nftCountry, nftCountry,
nftColor, // e.g., '[red]', Color in IntValue nftColor, // e.g., '[red]', Color in IntValue
nftCompareOp, nftCompareOp,
@ -89,7 +89,7 @@ type
TsNumFormatKind = (nfkPercent, nfkExp, nfkCurrency, nfkFraction, TsNumFormatKind = (nfkPercent, nfkExp, nfkCurrency, nfkFraction,
nfkDate, nfkTime, nfkTimeInterval, nfkHasColor, nfkHasThSep, nfkHasFactor); nfkDate, nfkTime, nfkTimeInterval, nfkHasColor, nfkHasThSep, nfkHasFactor);
{@@ Set of summary elements classifying and describing a number format ssection } {@@ Set of summary elements classifying and describing a number format section }
TsNumFormatKinds = set of TsNumFormatKind; TsNumFormatKinds = set of TsNumFormatKind;
{@@ Number format string can be composed of several parts separated by a {@@ Number format string can be composed of several parts separated by a
@ -100,7 +100,7 @@ type
Elements: TsNumFormatElements; Elements: TsNumFormatElements;
{@@ Summary information describing the section } {@@ Summary information describing the section }
Kind: TsNumFormatKinds; Kind: TsNumFormatKinds;
{@@ Reconstructed number format identifier for the builtin fps formats } {@@ Reconstructed number format identifier for the built-in fps formats }
NumFormat: TsNumberFormat; NumFormat: TsNumberFormat;
{@@ Number of decimal places used by the format string } {@@ Number of decimal places used by the format string }
Decimals: Byte; Decimals: Byte;
@ -126,8 +126,9 @@ type
{ TsNumFormatParams } { TsNumFormatParams }
{@@ Describes a pared number format and provides all the information to {@@ Describes a parsed number format and provides all the information to
convert a number to a number or date/time string. } convert a number to a number or date/time string. These data are created
by the number format parser from a format string. }
TsNumFormatParams = class(TObject) TsNumFormatParams = class(TObject)
private private
protected protected
@ -148,6 +149,7 @@ type
property NumFormatStr: String read GetNumFormatStr; property NumFormatStr: String read GetNumFormatStr;
end; end;
{ TsNumFormatList } { TsNumFormatList }
{@@ Class of number format parameters } {@@ Class of number format parameters }
@ -220,8 +222,6 @@ function IsTimeIntervalFormat(ANumFormat: TsNumFormatParams): Boolean;
function MakeLongDateFormat(ADateFormat: String): String; function MakeLongDateFormat(ADateFormat: String): String;
function MakeShortDateFormat(ADateFormat: String): String; function MakeShortDateFormat(ADateFormat: String): String;
procedure MakeTimeIntervalMask(Src: String; var Dest: String); procedure MakeTimeIntervalMask(Src: String; var Dest: String);
function SpecialDateTimeFormat(ACode: String;
const AFormatSettings: TFormatSettings; ForWriting: Boolean): String;
function StripAMPM(const ATimeFormatString: String): String; function StripAMPM(const ATimeFormatString: String): String;
@ -234,20 +234,19 @@ uses
const const
{@@ Array of format strings identifying the order of number and {@@ Array of format strings identifying the order of number and
currency symbol of a positive currency value. The number is expected at currency symbol of a positive currency value. The number is expected at
index 0, the currency symbol at index 1 of the parameter array of the index 0, the currency symbol at index 1 of the parameter array used by the
fpc format() function. } fpc Format() function. }
POS_CURR_FMT: array[0..3] of string = ( POS_CURR_FMT: array[0..3] of string = (
// Format parameter 0 is "value", parameter 1 is "currency symbol"
('%1:s%0:s'), // 0: $1 ('%1:s%0:s'), // 0: $1
('%0:s%1:s'), // 1: 1$ ('%0:s%1:s'), // 1: 1$
('%1:s %0:s'), // 2: $ 1 ('%1:s %0:s'), // 2: $ 1
('%0:s %1:s') // 3: 1 $ ('%0:s %1:s') // 3: 1 $
); );
{@@ Array of format strings identifying the order of number and {@@ Array of format strings identifying the order of number and
currency symbol of a negative currency value. This sign is shown currency symbol of a negative currency value. The sign is shown
by a dash character ("-") or by means of brackets. The number as a dash character ("-") or by means of brackets. The number
is expected at index 0, the currency symbol at index 1 of the is expected at index 0, the currency symbol at index 1 of the
parameter array for the fpc format() function. } parameter array for the fpc Format() function. }
NEG_CURR_FMT: array[0..15] of string = ( NEG_CURR_FMT: array[0..15] of string = (
('(%1:s%0:s)'), // 0: ($1) ('(%1:s%0:s)'), // 0: ($1)
('-%1:s%0:s'), // 1: -$1 ('-%1:s%0:s'), // 1: -$1
@ -276,22 +275,22 @@ type
TsNumFormatTokenSet = set of TsNumFormatToken; TsNumFormatTokenSet = set of TsNumFormatToken;
const const
{@@ Set of tokens which terminate a number } {@@ Set of tokens which terminate number information in a format string }
TERMINATING_TOKENS: TsNumFormatTokenSet = TERMINATING_TOKENS: TsNumFormatTokenSet =
[nftSpace, nftText, nftEscaped, nftPercent, nftCurrSymbol, nftSign, nftSignBracket]; [nftSpace, nftText, nftEscaped, nftPercent, nftCurrSymbol, nftSign, nftSignBracket];
{@@ Set of tokens which describe the integer part of a number } {@@ Set of tokens which describe the integer part of a number format }
INT_TOKENS: TsNumFormatTokenSet = INT_TOKENS: TsNumFormatTokenSet =
[nftIntOptDigit, nftIntZeroDigit, nftIntSpaceDigit]; [nftIntOptDigit, nftIntZeroDigit, nftIntSpaceDigit];
{@@ Set of tokens which describe the decimals of a number } {@@ Set of tokens which describe the decimals of a number format }
DECS_TOKENS: TsNumFormatTokenSet = DECS_TOKENS: TsNumFormatTokenSet =
[nftZeroDecs, nftOptDecs, nftSpaceDecs]; [nftZeroDecs, nftOptDecs, nftSpaceDecs];
{@@ Set of tokens which describe the numerator of a fraction } {@@ Set of tokens which describe the numerator of a fraction format }
FRACNUM_TOKENS: TsNumFormatTokenSet = FRACNUM_TOKENS: TsNumFormatTokenSet =
[nftFracNumOptDigit, nftFracNumZeroDigit, nftFracNumSpaceDigit]; [nftFracNumOptDigit, nftFracNumZeroDigit, nftFracNumSpaceDigit];
{@@ Set of tokens which describe the denominator of a fraction } {@@ Set of tokens which describe the denominator of a fraction format }
FRACDENOM_TOKENS: TsNumFormatTokenSet = FRACDENOM_TOKENS: TsNumFormatTokenSet =
[nftFracDenomOptDigit, nftFracDenomZeroDigit, nftFracDenomSpaceDigit, nftFracDenom]; [nftFracDenomOptDigit, nftFracDenomZeroDigit, nftFracDenomSpaceDigit, nftFracDenom];
{@@ Set of tokens which describe the exponent in exponential presentation of a number } {@@ Set of tokens which describe the exponent in exponential formatting of a number }
EXP_TOKENS: TsNumFormatTokenSet = EXP_TOKENS: TsNumFormatTokenSet =
[nftExpDigits]; // todo: expand by optional digits (0.00E+#) [nftExpDigits]; // todo: expand by optional digits (0.00E+#)
@ -734,7 +733,7 @@ end;
number format parameters number format parameters
@param AValue Value to be converted to a string @param AValue Value to be converted to a string
@param AParams Number format params which will be applied in the @param AParams Number format parameters which will be applied in the
conversion. The number format params are obtained conversion. The number format params are obtained
by the number format parser from the number format by the number format parser from the number format
string. string.
@ -938,7 +937,7 @@ end;
{@@ ---------------------------------------------------------------------------- {@@ ----------------------------------------------------------------------------
Adds an AM/PM format code to a pre-built time formatting string. The strings Adds an AM/PM format code to a pre-built time formatting string. The strings
replacing "AM" or "PM" in the final formatted number are taken from the replacing "AM" or "PM" in the final formatted number are taken from the
TimeAMString or TimePMString of the given FormatSettings. TimeAMString or TimePMString of the specified FormatSettings.
@param ATimeFormatString String of time formatting codes (such as 'hh:nn') @param ATimeFormatString String of time formatting codes (such as 'hh:nn')
@param AFormatSettings FormatSettings for locale-dependent information @param AFormatSettings FormatSettings for locale-dependent information
@ -964,7 +963,7 @@ end;
@param AFormatString String with time formatting codes @param AFormatString String with time formatting codes
@return Unchanged format string if its first time code is in square brackets @return Unchanged format string if its first time code is in square brackets
(as in '[h]:nn:ss'), if not, the first time code is enclosed in (as in '[h]:nn:ss'). If not, the first time code is enclosed in
square brackets. square brackets.
-------------------------------------------------------------------------------} -------------------------------------------------------------------------------}
function AddIntervalBrackets(AFormatString: String): String; function AddIntervalBrackets(AFormatString: String): String;
@ -1034,22 +1033,24 @@ end;
@param ANumberFormat Identifier of the built-in number format for which the @param ANumberFormat Identifier of the built-in number format for which the
format string is to be generated. format string is to be generated.
@param AFormatSettings FormatSettings to be applied (used to extract default @param AFormatSettings FormatSettings to be applied (used to extract default
values for the next parameters) values for the parameters following)
@param ADecimals number of decimal places. If < 0, the CurrencyDecimals @param ADecimals number of decimal places. If < 0, the CurrencyDecimals
of the FormatSettings is used. of the FormatSettings is used.
@param APosCurrFmt Identifier for the order of currency symbol, value and @param APosCurrFmt Identifier for the order of currency symbol, value and
spaces of positive values spaces of positive values
- see pcfXXXX constants in fpspreadsheet.pas. - see pcfXXXX constants in fpsTypes.pas.
If < 0, the CurrencyFormat of the FormatSettings is used. If < 0, the CurrencyFormat of the FormatSettings is used.
@param ANegCurrFmt Identifier for the order of currency symbol, value and @param ANegCurrFmt Identifier for the order of currency symbol, value and
spaces of negative values. Specifies also usage of (). spaces of negative values. Specifies also usage of ().
- see ncfXXXX constants in fpspreadsheet.pas. - see ncfXXXX constants in fpsTypes.pas.
If < 0, the NegCurrFormat of the FormatSettings is used. If < 0, the NegCurrFormat of the FormatSettings is used.
@param ACurrencySymbol Name of the currency, like $ or USD. @param ACurrencySymbol String to identify the currency, like $ or USD.
If ? the CurrencyString of the FormatSettings is used. If ? the CurrencyString of the FormatSettings is used.
@param Accounting If true, adds spaces for alignment of decimals @param Accounting If true, adds spaces for alignment of decimals
@return String of formatting codes, such as '"$"#,##0.00;("$"#,##0.00);"$"0.00' @return String of formatting codes
@example '"$"#,##0.00;("$"#,##0.00);"$"0.00'
-------------------------------------------------------------------------------} -------------------------------------------------------------------------------}
function BuildCurrencyFormatString(ANumberFormat: TsNumberFormat; function BuildCurrencyFormatString(ANumberFormat: TsNumberFormat;
const AFormatSettings: TFormatSettings; const AFormatSettings: TFormatSettings;
@ -1185,9 +1186,11 @@ end;
Builds a number format string for fraction formatting from the number format Builds a number format string for fraction formatting from the number format
code and the count of numerator and denominator digits. code and the count of numerator and denominator digits.
@param AMixedFraction If TRUE fraction is presented as mixed fraction @param AMixedFraction If TRUE, fraction is presented as mixed fraction
@param ANumeratorDigits Count of numerator digits @param ANumeratorDigits Count of numerator digits
@param ADenominatorDigits Count of denominator digits @param ADenominatorDigits Count of denominator digits. If the value is negative
then its absolute value is inserted literally as
as denominator.
@return String of formatting code, here something like: '##/##' or '# ##/##' @return String of formatting code, here something like: '##/##' or '# ##/##'
-------------------------------------------------------------------------------} -------------------------------------------------------------------------------}
@ -1262,8 +1265,8 @@ end;
{@@ ---------------------------------------------------------------------------- {@@ ----------------------------------------------------------------------------
Creates a format string for the specified parsed number format section. Creates a format string for the specified parsed number format section.
The format string is created according to Excel convention (which is used by The format string is created according to Excel convention (which is understood
ODS as well. by ODS as well).
@param ASection Parsed section of number format elements as created by the @param ASection Parsed section of number format elements as created by the
number format parser number format parser
@ -1369,7 +1372,7 @@ begin
end; end;
{@@ ---------------------------------------------------------------------------- {@@ ----------------------------------------------------------------------------
Counts how many decimal places are coded into a given formatting string. Counts how many decimal places are coded into a given number format string.
@param AFormatString String with number format codes, such as '0.000' @param AFormatString String with number format codes, such as '0.000'
@param ADecChars Characters which are considered as symbols for decimals. @param ADecChars Characters which are considered as symbols for decimals.
@ -1398,7 +1401,7 @@ end;
{@@ ---------------------------------------------------------------------------- {@@ ----------------------------------------------------------------------------
Checks whether the given number format code is for currency, Checks whether the given number format code is for currency,
i.e. requires currency symbol. i.e. requires a currency symbol.
@param AFormat Built-in number format identifier to be checked @param AFormat Built-in number format identifier to be checked
@return True if AFormat is nfCurrency or nfCurrencyRed, false otherwise. @return True if AFormat is nfCurrency or nfCurrencyRed, false otherwise.
@ -1472,11 +1475,12 @@ end;
@param ANumFormat Number format parameters @param ANumFormat Number format parameters
@return True if Kind of the 1st format parameter section contains the @return True if Kind of the 1st format parameter section contains the
nfkDate, but no nfkTime elements; false otherwise nfkDate, but no nfkTime tags; false otherwise
-------------------------------------------------------------------------------} -------------------------------------------------------------------------------}
function IsDateFormat(ANumFormat: TsNumFormatParams): Boolean; function IsDateFormat(ANumFormat: TsNumFormatParams): Boolean;
begin begin
Result := (ANumFormat <> nil) and (nfkDate in ANumFormat.Sections[0].Kind); Result := (ANumFormat <> nil) and
(ANumFormat.Sections[0].Kind * [nfkDate, nfkTime] = [nfkDate]);
end; end;
{@@ ---------------------------------------------------------------------------- {@@ ----------------------------------------------------------------------------
@ -1519,7 +1523,7 @@ end;
function IsTimeFormat(ANumFormat: TsNumFormatParams): Boolean; function IsTimeFormat(ANumFormat: TsNumFormatParams): Boolean;
begin begin
Result := (ANumFormat <> nil) and Result := (ANumFormat <> nil) and
(ANumFormat.Sections[0].Kind * [nfkTime] <> []); (ANumFormat.Sections[0].Kind * [nfkTime, nfkDate] = [nfkTime]);
end; end;
{@@ ---------------------------------------------------------------------------- {@@ ----------------------------------------------------------------------------
@ -1646,51 +1650,6 @@ begin
end; end;
end; end;
{@@ ----------------------------------------------------------------------------
Creates the formatstrings for the date/time codes "dm", "my", "ms" and "msz"
out of the formatsettings.
@param ACode Quick formatting code for parts of date/time number formats;
"dm" = day + month
"my" = month + year
"ms" = minutes + seconds
"msz" = minutes + seconds + fractions of a second
@return String of formatting codes according to the parameter ACode
-------------------------------------------------------------------------------}
function SpecialDateTimeFormat(ACode: String;
const AFormatSettings: TFormatSettings; ForWriting: Boolean): String;
var
pd, pm, py: Integer;
sdf: String;
MonthChar, MinuteChar, MillisecChar: Char;
begin
if ForWriting then begin
MonthChar := 'M'; MinuteChar := 'm'; MillisecChar := '0';
end else begin
MonthChar := 'm'; MinuteChar := 'n'; MillisecChar := 'z';
end;
ACode := lowercase(ACode);
sdf := lowercase(AFormatSettings.ShortDateFormat);
pd := pos('d', sdf);
pm := pos('m', sdf);
py := pos('y', sdf);
if ACode = 'dm' then begin
Result := DupeString(MonthChar, 3);
Result := IfThen(pd < py, 'd/'+Result, Result+'/d'); // d/mmm
end else
if ACode = 'my' then begin
Result := DupeString(MonthChar, 3);
Result := IfThen(pm < py, Result+'/yy', 'yy/'+Result); // mmm/yy
end else
if ACode = 'ms' then begin
Result := DupeString(MinuteChar, 2) + ':ss'; // mm:ss
end
else if ACode = 'msz' then
Result := DupeString(MinuteChar, 2) + ':ss.' + MillisecChar // mm:ss.z
else
Result := ACode;
end;
{@@ ---------------------------------------------------------------------------- {@@ ----------------------------------------------------------------------------
Removes an AM/PM formatting code from a given time formatting string. Variants Removes an AM/PM formatting code from a given time formatting string. Variants
of "AM/PM" are considered as well. The string is left unchanged if it does not of "AM/PM" are considered as well. The string is left unchanged if it does not
@ -1722,7 +1681,7 @@ end;
{==============================================================================} {==============================================================================}
{@@ ---------------------------------------------------------------------------- {@@ ----------------------------------------------------------------------------
Deletes a parsed format element from the specified format section. Deletes a parsed number format element from the specified format section.
@param ASectionIndex Index of the format section containing the element to @param ASectionIndex Index of the format section containing the element to
be deleted be deleted
@ -1735,17 +1694,17 @@ begin
with Sections[ASectionIndex] do with Sections[ASectionIndex] do
begin begin
n := Length(Elements); n := Length(Elements);
for i:=AElementIndex+1 to n-1 do for i := AElementIndex+1 to n-1 do
Elements[i-1] := Elements[i]; Elements[i-1] := Elements[i];
SetLength(Elements, n-1); SetLength(Elements, n-1);
end; end;
end; end;
{@@ ---------------------------------------------------------------------------- {@@ ----------------------------------------------------------------------------
Creates the built-in number format identifier from the pared number format Creates the built-in number format identifier from the parsed number format
sections and elements sections and elements
@return Built-in number format identifer if the format is a built into @return Built-in number format identifer if the format is built into
fpspreadsheet, or nfCustom otherwise fpspreadsheet, or nfCustom otherwise
@see TsNumFormat @see TsNumFormat
@ -1769,8 +1728,8 @@ begin
end; end;
{@@ ---------------------------------------------------------------------------- {@@ ----------------------------------------------------------------------------
Constructs the number format string fromt the parsed sections and elements. Constructs the number format string from the parsed sections and elements.
The format sysmbols are selected according to Excel syntax. The format symbols are selected according to Excel syntax.
@return Excel-compatible number format string. @return Excel-compatible number format string.
-------------------------------------------------------------------------------} -------------------------------------------------------------------------------}
@ -1814,8 +1773,8 @@ begin
end; end;
{@@ ---------------------------------------------------------------------------- {@@ ----------------------------------------------------------------------------
Checks whether the parsed format sections passed as a parameter is identical Checks whether the parsed format sections passed as a parameter are identical
with the interal section array. to the interal section array.
@param ASections Array of parsed format sections to be compared with the @param ASections Array of parsed format sections to be compared with the
internal format sections internal format sections
@ -1885,7 +1844,7 @@ begin
end; end;
{@@ ---------------------------------------------------------------------------- {@@ ----------------------------------------------------------------------------
Defines the currency symbol used by the format sequence Defines the currency symbol used in the format params sequence
@param AValue String containing the currency symbol to be used in the @param AValue String containing the currency symbol to be used in the
converted numbers converted numbers
@ -1910,7 +1869,7 @@ end;
{@@ ---------------------------------------------------------------------------- {@@ ----------------------------------------------------------------------------
Adds or modifies parsed format tokens such that the specified number of Adds or modifies parsed format tokens such that the specified number of
decimal places is shown decimal places is displayed
@param AValue Number of decimal places to be shown @param AValue Number of decimal places to be shown
-------------------------------------------------------------------------------} -------------------------------------------------------------------------------}
@ -1936,10 +1895,10 @@ begin
end; end;
{@@ ---------------------------------------------------------------------------- {@@ ----------------------------------------------------------------------------
If AEnable is true a format section for negative number is added (or an If AEnable is true a format section for negative numbers is added (or an
existing one is modified) such that negative numbers are displayed in red. existing one is modified) such that negative numbers are displayed in red.
If AEnable is false the format tokens are modified such that negative values If AEnable is false the format tokens are modified such that negative values
are displayed in black are displayed in default color.
@param AEnable The format tokens are modified such as to display negative @param AEnable The format tokens are modified such as to display negative
values in red if AEnable is true. values in red if AEnable is true.
@ -2127,7 +2086,7 @@ begin
end; end;
{@@ ---------------------------------------------------------------------------- {@@ ----------------------------------------------------------------------------
Deletes the number format item having in the list the specified index Deletes the number format item having the specified index in the list.
If the list "owns" the format items, the item is destroyed. If the list "owns" the format items, the item is destroyed.
@param AIndex Index of the format item to be deleted @param AIndex Index of the format item to be deleted
@ -2171,7 +2130,7 @@ end;
Should be called before adding a format to the list to avoid duplicates. Should be called before adding a format to the list to avoid duplicates.
@param AFormatStr Number format string of the format item which is seeked @param AFormatStr Number format string of the format item which is seeked
@return Index of the found format item, or -1 if not found @return Index of the found format item, or -1 if not found
@see TsNumFormatList.Add @see TsNumFormatList.Add
-------------------------------------------------------------------------------} -------------------------------------------------------------------------------}
@ -2187,8 +2146,8 @@ begin
end; end;
{@@ ---------------------------------------------------------------------------- {@@ ----------------------------------------------------------------------------
Getter function returning the correct type of the list items: TsNumFormatParams Getter function returning the correct type of the list items
which are parsed format descriptions (i.e., TsNumFormatParams which are parsed format descriptions).
@param AIndex Index of the format item @param AIndex Index of the format item
@return Pointer to the list item at the specified index, cast to the type @return Pointer to the list item at the specified index, cast to the type

View File

@ -230,7 +230,7 @@ implementation
uses uses
StrUtils, Variants, LazFileUtils, URIParser, StrUtils, Variants, LazFileUtils, URIParser,
fpsStrings, fpsStreams, fpsExprParser; fpsStrings, fpsStreams, fpsClasses, fpsExprParser;
const const
{ OpenDocument general XML constants } { OpenDocument general XML constants }

View File

@ -554,28 +554,6 @@ type
{@@ Pointer to a format record } {@@ Pointer to a format record }
PsCellFormat = ^TsCellFormat; PsCellFormat = ^TsCellFormat;
{@@ Specialized list for format records }
TsCellFormatList = class(TFPList)
private
FAllowDuplicates: Boolean;
function GetItem(AIndex: Integer): PsCellFormat;
procedure SetItem(AIndex: Integer; const AValue: PsCellFormat);
public
constructor Create(AAllowDuplicates: Boolean);
destructor Destroy; override;
function Add(const AItem: TsCellFormat): Integer; overload;
function Add(AItem: PsCellFormat): Integer; overload;
procedure Clear;
procedure Delete(AIndex: Integer);
function FindIndexOfID(ID: Integer): Integer;
function FindIndexOfName(AName: String): Integer;
function IndexOf(const AItem: TsCellFormat): Integer; overload;
property Items[AIndex: Integer]: PsCellFormat read GetItem write SetItem; default;
end;
{@@ Pointer to a TCell record }
PCell = ^TCell;
{@@ Cell structure for TsWorksheet {@@ Cell structure for TsWorksheet
The cell record contains information on the location of the cell (row and The cell record contains information on the location of the cell (row and
column index), on the value contained (number, date, text, ...), on column index), on the value contained (number, date, text, ...), on
@ -608,15 +586,22 @@ type
cctError : (ErrorValue: TsErrorValue); cctError : (ErrorValue: TsErrorValue);
end; end;
{@@ Pointer to a TCell record }
PCell = ^TCell;
{@@ Page orientation for printing }
TsPageOrientation = (spoPortrait, spoLandscape); TsPageOrientation = (spoPortrait, spoLandscape);
{@@ Options for the print layout records }
TsPrintOption = (poPrintGridLines, poPrintHeaders, poPrintPagesByRows, TsPrintOption = (poPrintGridLines, poPrintHeaders, poPrintPagesByRows,
poMonochrome, poDraftQuality, poPrintCellComments, poDefaultOrientation, poMonochrome, poDraftQuality, poPrintCellComments, poDefaultOrientation,
poUseStartPageNumber, poCommentsAtEnd, poHorCentered, poVertCentered, poUseStartPageNumber, poCommentsAtEnd, poHorCentered, poVertCentered,
poDifferentOddEven, poDifferentFirst, poFitPages); poDifferentOddEven, poDifferentFirst, poFitPages);
{@@ Set of options used by the page layout }
TsPrintOptions = set of TsPrintOption; TsPrintOptions = set of TsPrintOption;
{@@ Record defining parameters for printing by the Office applications }
TsPageLayout = record // all lengths in mm TsPageLayout = record // all lengths in mm
Orientation: TsPageOrientation; Orientation: TsPageOrientation;
PageWidth: Double; // for "normal" orientation (mostly portrait) PageWidth: Double; // for "normal" orientation (mostly portrait)
@ -654,6 +639,7 @@ type
Footers: array[0..2] of string; Footers: array[0..2] of string;
end; end;
{@@ Pointer to a page layout record }
PsPageLayout = ^TsPageLayout; PsPageLayout = ^TsPageLayout;
const const
@ -666,174 +652,5 @@ const
implementation implementation
{ TsCellFormatList }
constructor TsCellFormatList.Create(AAllowDuplicates: Boolean);
begin
inherited Create;
FAllowDuplicates := AAllowDuplicates;
end;
destructor TsCellFormatList.Destroy;
begin
Clear;
inherited;
end;
function TsCellFormatList.Add(const AItem: TsCellFormat): Integer;
var
P: PsCellFormat;
begin
if FAllowDuplicates then
Result := -1
else
Result := IndexOf(AItem);
if Result = -1 then begin
New(P);
P^.Name := AItem.Name;
P^.ID := AItem.ID;
P^.UsedFormattingFields := AItem.UsedFormattingFields;
P^.FontIndex := AItem.FontIndex;
P^.TextRotation := AItem.TextRotation;
P^.HorAlignment := AItem.HorAlignment;
P^.VertAlignment := AItem.VertAlignment;
P^.Border := AItem.Border;
P^.BorderStyles := AItem.BorderStyles;
P^.Background := AItem.Background;
P^.NumberFormatIndex := AItem.NumberFormatIndex;
P^.NumberFormat := AItem.NumberFormat;
P^.NumberFormatStr := AItem.NumberFormatStr;
Result := inherited Add(P);
end;
end;
{@@ ----------------------------------------------------------------------------
Adds a pointer to a FormatRecord to the list. Allows nil for the predefined
formats which are not stored in the file.
-------------------------------------------------------------------------------}
function TsCellFormatList.Add(AItem: PsCellFormat): Integer;
begin
if AItem = nil then
Result := inherited Add(AItem)
else
Result := Add(AItem^);
end;
procedure TsCellFormatList.Clear;
var
i: Integer;
begin
for i:=Count-1 downto 0 do
Delete(i);
inherited;
end;
procedure TsCellFormatList.Delete(AIndex: Integer);
var
P: PsCellFormat;
begin
P := GetItem(AIndex);
if P <> nil then
Dispose(P);
inherited Delete(AIndex);
end;
function TsCellFormatList.GetItem(AIndex: Integer): PsCellFormat;
begin
Result := inherited Items[AIndex];
end;
function TsCellFormatList.FindIndexOfID(ID: Integer): Integer;
var
P: PsCellFormat;
begin
for Result := 0 to Count-1 do
begin
P := GetItem(Result);
if (P <> nil) and (P^.ID = ID) then
exit;
end;
Result := -1;
end;
function TsCellFormatList.FindIndexOfName(AName: String): Integer;
var
P: PsCellFormat;
begin
for Result := 0 to Count-1 do
begin
P := GetItem(Result);
if (P <> nil) and (P^.Name = AName) then
exit;
end;
Result := -1;
end;
function TsCellFormatList.IndexOf(const AItem: TsCellFormat): Integer;
var
P: PsCellFormat;
equ: Boolean;
b: TsCellBorder;
begin
for Result := 0 to Count-1 do
begin
P := GetItem(Result);
if (P = nil) then continue;
if (P^.UsedFormattingFields <> AItem.UsedFormattingFields) then continue;
if (uffFont in AItem.UsedFormattingFields) then
if (P^.FontIndex) <> (AItem.FontIndex) then continue;
if (uffTextRotation in AItem.UsedFormattingFields) then
if (P^.TextRotation <> AItem.TextRotation) then continue;
if (uffHorAlign in AItem.UsedFormattingFields) then
if (P^.HorAlignment <> AItem.HorAlignment) then continue;
if (uffVertAlign in AItem.UsedFormattingFields) then
if (P^.VertAlignment <> AItem.VertAlignment) then continue;
if (uffBorder in AItem.UsedFormattingFields) then
if (P^.Border <> AItem.Border) then continue;
// Border styles can be set even if borders are not used --> don't check uffBorder!
equ := true;
for b in AItem.Border do begin
if (P^.BorderStyles[b].LineStyle <> AItem.BorderStyles[b].LineStyle) or
(P^.BorderStyles[b].Color <> Aitem.BorderStyles[b].Color)
then begin
equ := false;
break;
end;
end;
if not equ then continue;
if (uffBackground in AItem.UsedFormattingFields) then begin
if (P^.Background.Style <> AItem.Background.Style) then continue;
if (P^.Background.BgColor <> AItem.Background.BgColor) then continue;
if (P^.Background.FgColor <> AItem.Background.FgColor) then continue;
end;
if (uffNumberFormat in AItem.UsedFormattingFields) then begin
if (P^.NumberFormatIndex <> AItem.NumberFormatIndex) then continue;
if (P^.NumberFormat <> AItem.NumberFormat) then continue;
if (P^.NumberFormatStr <> AItem.NumberFormatStr) then continue;
end;
// If we arrive here then the format records match.
exit;
end;
// We get here if no record matches
Result := -1;
end;
procedure TsCellFormatList.SetItem(AIndex: Integer; const AValue: PsCellFormat);
begin
inherited Items[AIndex] := AValue;
end;
end. end.

View File

@ -230,10 +230,6 @@ begin
SollNumberStrings[i, 5] := FormatFloat('0.00E+00', SollNumbers[i], fs); SollNumberStrings[i, 5] := FormatFloat('0.00E+00', SollNumbers[i], fs);
SollNumberStrings[i, 6] := FormatFloat('0', SollNumbers[i]*100, fs) + '%'; SollNumberStrings[i, 6] := FormatFloat('0', SollNumbers[i]*100, fs) + '%';
SollNumberStrings[i, 7] := FormatFloat('0.00', SollNumbers[i]*100, fs) + '%'; SollNumberStrings[i, 7] := FormatFloat('0.00', SollNumbers[i]*100, fs) + '%';
{
SollNumberStrings[i, 8] := FormatCurr('"€"#,##0;("€"#,##0)', SollNumbers[i], fs);
SollNumberStrings[i, 9] := FormatCurr('"€"#,##0.00;("€"#,##0.00)', SollNumbers[i], fs);
}
// Don't use FormatCurr for the next two cases because is reports the sign of // Don't use FormatCurr for the next two cases because is reports the sign of
// very small numbers inconsistenly with the spreadsheet applications. // very small numbers inconsistenly with the spreadsheet applications.
SollNumberStrings[i, 8] := FormatFloat('"€"#,##0;("€"#,##0)', SollNumbers[i], fs); SollNumberStrings[i, 8] := FormatFloat('"€"#,##0;("€"#,##0)', SollNumbers[i], fs);
@ -266,9 +262,9 @@ begin
SolLDateTimeStrings[i, 3] := FormatDateTime(fs.LongTimeFormat, SollDateTimes[i], fs); SolLDateTimeStrings[i, 3] := FormatDateTime(fs.LongTimeFormat, SollDateTimes[i], fs);
SollDateTimeStrings[i, 4] := FormatDateTime(fs.ShortTimeFormat + ' am/pm', SollDateTimes[i], fs); // dont't use "t" - it does the hours wrong SollDateTimeStrings[i, 4] := FormatDateTime(fs.ShortTimeFormat + ' am/pm', SollDateTimes[i], fs); // dont't use "t" - it does the hours wrong
SollDateTimeStrings[i, 5] := FormatDateTime(fs.LongTimeFormat + ' am/pm', SollDateTimes[i], fs); SollDateTimeStrings[i, 5] := FormatDateTime(fs.LongTimeFormat + ' am/pm', SollDateTimes[i], fs);
SollDateTimeStrings[i, 6] := FormatDateTime(SpecialDateTimeFormat('dm', fs, false), SollDateTimes[i], fs); SollDateTimeStrings[i, 6] := FormatDateTime('dd/mmm', SollDateTimes[i], fs);
SollDateTimeStrings[i, 7] := FormatDateTime(SpecialDateTimeFormat('my', fs, false), SollDateTimes[i], fs); SollDateTimeStrings[i, 7] := FormatDateTime('mmm/yy', SollDateTimes[i], fs);
SollDateTimeStrings[i, 8] := FormatDateTime(SpecialDateTimeFormat('ms', fs, false), SollDateTimes[i], fs); SollDateTimeStrings[i, 8] := FormatDateTime('nn:ss', 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; end;

View File

@ -565,7 +565,8 @@ implementation
uses uses
AVL_Tree, Math, Variants, AVL_Tree, Math, Variants,
{%H-}fpspatches, fpsStrings, fpsNumFormat, xlsConst, fpsrpn, fpsExprParser; {%H-}fpspatches, fpsStrings, fpsClasses, fpsNumFormat, xlsConst,
fpsrpn, fpsExprParser;
const const
{ Helper table for rpn formulas: { Helper table for rpn formulas:

View File

@ -206,17 +206,17 @@ implementation
uses uses
variants, fileutil, strutils, math, lazutf8, uriparser, variants, fileutil, strutils, math, lazutf8, uriparser,
{%H-}fpsPatches, fpsStrings, fpsStreams, fpsNumFormatParser; {%H-}fpsPatches, fpsStrings, fpsStreams, fpsNumFormatParser, fpsClasses;
const const
{ OOXML general XML constants } { OOXML general XML constants }
XML_HEADER = '<?xml version="1.0" encoding="utf-8" ?>'; XML_HEADER = '<?xml version="1.0" encoding="utf-8" ?>';
{ OOXML Directory structure constants } { OOXML Directory structure constants }
// Note: directory separators are always / because the .xlsx is a zip file which // Note: directory separators are always / because the .xlsx is a zip file which
// requires / instead of \, even on Windows; see // requires / instead of \, even on Windows; see
// http://www.pkware.com/documents/casestudies/APPNOTE.TXT // http://www.pkware.com/documents/casestudies/APPNOTE.TXT
// 4.4.17.1 All slashes MUST be forward slashes '/' as opposed to backwards slashes '\' // 4.4.17.1 All slashes MUST be forward slashes '/' as opposed to backward slashes '\'
OOXML_PATH_TYPES = '[Content_Types].xml'; OOXML_PATH_TYPES = '[Content_Types].xml';
{%H-}OOXML_PATH_RELS = '_rels/'; {%H-}OOXML_PATH_RELS = '_rels/';
OOXML_PATH_RELS_RELS = '_rels/.rels'; OOXML_PATH_RELS_RELS = '_rels/.rels';