Files
lazarus-ccr/components/fpspreadsheet/fpsnumformat.pas

324 lines
10 KiB
ObjectPascal
Raw Normal View History

unit fpsNumFormat;
{$ifdef fpc}
{$mode objfpc}{$H+}
{$endif}
interface
uses
Classes, SysUtils,
fpstypes, fpspreadsheet;
type
{ TsNumFormatList }
TsNumFormatList = class(TFPList)
private
FOwnsData: Boolean;
function GetItem(AIndex: Integer): TsNumFormatParams;
procedure SetItem(AIndex: Integer; const AValue: TsNumFormatParams);
protected
FWorkbook: TsWorkbook;
FClass: TsNumFormatParamsClass;
procedure AddBuiltinFormats; virtual;
public
constructor Create(AWorkbook: TsWorkbook; AOwnsData: Boolean);
destructor Destroy; override;
function AddFormat(ASections: TsNumFormatSections): Integer; overload;
function AddFormat(AFormatStr: String): Integer; overload;
procedure Clear;
procedure Delete(AIndex: Integer);
function Find(ASections: TsNumFormatSections): Integer; overload;
function Find(AFormatstr: String): Integer; overload;
property Items[AIndex: Integer]: TsNumFormatParams read GetItem write SetItem; default;
{@@ Workbook from which the number formats are collected in the list. It is
mainly needed to get access to the FormatSettings for easy localization of
some formatting strings. }
property Workbook: TsWorkbook read FWorkbook;
end;
function IsCurrencyFormat(AFormat: TsNumberFormat): Boolean; overload;
function IsCurrencyFormat(ANumFormat: TsNumFormatParams): Boolean; overload;
function IsDateTimeFormat(AFormat: TsNumberFormat): Boolean; overload;
function IsDateTimeFormat(AFormatStr: String): Boolean; overload;
function IsDateTimeFormat(ANumFormat: TsNumFormatParams): Boolean; overload;
function IsDateFormat(ANumFormat: TsNumFormatParams): Boolean;
function IsTimeFormat(AFormat: TsNumberFormat): Boolean; overload;
function IsTimeFormat(AFormatStr: String): Boolean; overload;
function IsTimeFormat(ANumFormat: TsNumFormatParams): Boolean; overload;
function IsLongTimeFormat(AFormatStr: String; ATimeSeparator: char): Boolean; overload;
function IsTimeIntervalFormat(ANumFormat: TsNumFormatParams): Boolean;
implementation
uses
fpsUtils, fpsNumFormatParser;
{@@ ----------------------------------------------------------------------------
Checks whether the given number format code is for currency,
i.e. requires currency symbol.
@param AFormat Built-in number format identifier to be checked
@return True if AFormat is nfCurrency or nfCurrencyRed, false otherwise.
-------------------------------------------------------------------------------}
function IsCurrencyFormat(AFormat: TsNumberFormat): Boolean;
begin
Result := AFormat in [nfCurrency, nfCurrencyRed];
end;
{@@ ----------------------------------------------------------------------------
Checks whether the specified number format parameters apply to currency values.
@param ANumFormat Number format parameters
@return True if Kind of the 1st format parameter section contains the
nfkCurrency elements; false otherwise
-------------------------------------------------------------------------------}
function IsCurrencyFormat(ANumFormat: TsNumFormatParams): Boolean;
begin
Result := (ANumFormat <> nil) and
(ANumFormat.Sections[0].Kind * [nfkCurrency] <> []);
end;
{@@ ----------------------------------------------------------------------------
Checks whether the given number format code is for date/time values.
@param AFormat Built-in number format identifier to be checked
@return True if AFormat is a date/time format (such as nfShortTime),
false otherwise
-------------------------------------------------------------------------------}
function IsDateTimeFormat(AFormat: TsNumberFormat): Boolean;
begin
Result := AFormat in [nfShortDateTime, nfShortDate, nfLongDate,
nfShortTime, nfLongTime, nfShortTimeAM, nfLongTimeAM,
nfDayMonth, nfMonthYear, nfTimeInterval];
end;
{@@ ----------------------------------------------------------------------------
Checks whether the given string with formatting codes is for date/time values.
@param AFormatStr String with formatting codes to be checked.
@return True if AFormatStr is a date/time format string (such as 'hh:nn'),
false otherwise
-------------------------------------------------------------------------------}
function IsDateTimeFormat(AFormatStr: string): Boolean;
var
parser: TsNumFormatParser;
begin
parser := TsNumFormatParser.Create(nil, AFormatStr);
try
Result := parser.IsDateTimeFormat;
finally
parser.Free;
end;
end;
{@@ ----------------------------------------------------------------------------
Checks whether the specified number format parameters apply to date/time values.
@param ANumFormat Number format parameters
@return True if Kind of the 1st format parameter section contains the
nfkDate or nfkTime elements; false otherwise
-------------------------------------------------------------------------------}
function IsDateTimeFormat(ANumFormat: TsNumFormatParams): Boolean;
begin
Result := (ANumFormat <> nil) and
(ANumFormat.Sections[0].Kind * [nfkDate, nfkTime] <> []);
end;
{@@ ----------------------------------------------------------------------------
Checks whether the specified number format parameters apply to a date value.
@param ANumFormat Number format parameters
@return True if Kind of the 1st format parameter section contains the
nfkDate, but no nfkTime elements; false otherwise
-------------------------------------------------------------------------------}
function IsDateFormat(ANumFormat: TsNumFormatParams): Boolean;
begin
Result := (ANumFormat <> nil) and (nfkDate in ANumFormat.Sections[0].Kind);
end;
{@@ ----------------------------------------------------------------------------
Checks whether the given built-in number format code is for time values.
@param AFormat Built-in number format identifier to be checked
@return True if AFormat represents to a time-format, false otherwise
-------------------------------------------------------------------------------}
function IsTimeFormat(AFormat: TsNumberFormat): boolean;
begin
Result := AFormat in [nfShortTime, nfLongTime, nfShortTimeAM, nfLongTimeAM,
nfTimeInterval];
end;
{@@ ----------------------------------------------------------------------------
Checks whether the given string with formatting codes is for time values.
@param AFormatStr String with formatting codes to be checked
@return True if AFormatStr represents a time-format, false otherwise
-------------------------------------------------------------------------------}
function IsTimeFormat(AFormatStr: String): Boolean;
var
parser: TsNumFormatParser;
begin
parser := TsNumFormatParser.Create(nil, AFormatStr);
try
Result := parser.IsTimeFormat;
finally
parser.Free;
end;
end;
{@@ ----------------------------------------------------------------------------
Checks whether the specified number format parameters apply to time values.
@param ANumFormat Number format parameters
@return True if Kind of the 1st format parameter section contains the
nfkTime, but no nfkDate elements; false otherwise
-------------------------------------------------------------------------------}
function IsTimeFormat(ANumFormat: TsNumFormatParams): Boolean;
begin
Result := (ANumFormat <> nil) and
(ANumFormat.Sections[0].Kind * [nfkTime] <> []);
end;
{@@ ----------------------------------------------------------------------------
Returns TRUE if the specified format string represents a long time format, i.e.
it contains two TimeSeparators.
-------------------------------------------------------------------------------}
function IsLongTimeFormat(AFormatStr: String; ATimeSeparator: Char): Boolean;
var
i, n: Integer;
begin
n := 0;
for i:=1 to Length(AFormatStr) do
if AFormatStr[i] = ATimeSeparator then inc(n);
Result := (n=2);
end;
{@@ ----------------------------------------------------------------------------
Checks whether the specified number format parameters is a time interval
format.
@param ANumFormat Number format parameters
@return True if Kind of the 1st format parameter section contains the
nfkTimeInterval elements; false otherwise
-------------------------------------------------------------------------------}
function IsTimeIntervalFormat(ANumFormat: TsNumFormatParams): Boolean;
begin
Result := (ANumFormat <> nil) and
(ANumFormat.Sections[0].Kind * [nfkTimeInterval] <> []);
end;
{ TsNumFormatList }
constructor TsNumFormatList.Create(AWorkbook: TsWorkbook; AOwnsData: Boolean);
begin
inherited Create;
FClass := TsNumFormatParams;
FWorkbook := AWorkbook;
FOwnsData := AOwnsData;
end;
destructor TsNumFormatList.Destroy;
begin
Clear;
inherited;
end;
function TsNumFormatList.AddFormat(ASections: TsNumFormatSections): Integer;
var
nfp: TsNumFormatParams;
begin
Result := Find(ASections);
if Result = -1 then begin
nfp := FClass.Create;
nfp.Sections := ASections;
Result := inherited Add(nfp);
end;
end;
function TsNumFormatList.AddFormat(AFormatStr: String): Integer;
var
parser: TsNumFormatParser;
newSections: TsNumFormatSections;
i: Integer;
begin
parser := TsNumFormatParser.Create(FWorkbook, AFormatStr);
try
SetLength(newSections, parser.ParsedSectionCount);
for i:=0 to High(newSections) do
newSections[i] := parser.ParsedSections[i];
Result := AddFormat(newSections);
finally
parser.Free;
end;
end;
procedure TsNumFormatList.AddBuiltinFormats;
begin
end;
procedure TsNumFormatList.Clear;
var
i: Integer;
begin
for i := Count-1 downto 0 do Delete(i);
inherited;
end;
procedure TsNumFormatList.Delete(AIndex: Integer);
var
p: TsNumFormatParams;
begin
if FOwnsData then
begin
p := GetItem(AIndex);
if p <> nil then p.Free;
end;
inherited Delete(AIndex);
end;
function TsNumFormatList.Find(ASections: TsNumFormatSections): Integer;
var
nfp: TsNumFormatParams;
begin
for Result := 0 to Count-1 do begin
nfp := GetItem(Result);
if nfp.SectionsEqualTo(ASections) then
exit;
end;
Result := -1;
end;
function TsNumFormatList.Find(AFormatStr: String): Integer;
var
nfp: TsNumFormatParams;
begin
nfp := CreateNumFormatParams(FWorkbook, AFormatStr);
if nfp = nil then
Result := -1
else
Result := Find(nfp.Sections);
end;
function TsNumFormatList.GetItem(AIndex: Integer): TsNumFormatParams;
begin
Result := TsNumFormatParams(inherited Items[AIndex]);
end;
procedure TsNumFormatList.SetItem(AIndex: Integer;
const AValue: TsNumFormatParams);
begin
inherited Items[AIndex] := AValue;
end;
end.