
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@5284 8e941d3f-bd1b-0410-a28a-d453659cc2b4
830 lines
23 KiB
ObjectPascal
830 lines
23 KiB
ObjectPascal
unit sNumFormatForm;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ButtonPanel,
|
|
ExtCtrls, StdCtrls, Spin, Buttons, types, inifiles,
|
|
fpsTypes, fpsNumFormat, fpSpreadsheet;
|
|
|
|
type
|
|
TsNumFormatCategory = (nfcNumber, nfcPercent, nfcScientific, nfcFraction,
|
|
nfcCurrency, nfcDate, nfcTime, nfcText);
|
|
|
|
{ TNumFormatForm }
|
|
|
|
TNumFormatForm = class(TForm)
|
|
ButtonPanel1: TButtonPanel;
|
|
CbThousandSep: TCheckBox;
|
|
CbNegRed: TCheckBox;
|
|
CbCurrSymbol: TComboBox;
|
|
EdNumFormatStr: TEdit;
|
|
GbOptions: TGroupBox;
|
|
GbFormatString: TGroupBox;
|
|
GroupBox3: TGroupBox;
|
|
Label1: TLabel;
|
|
Label2: TLabel;
|
|
Label3: TLabel;
|
|
DetailsPanel: TPanel;
|
|
Sample: TLabel;
|
|
Label5: TLabel;
|
|
LbCategory: TListBox;
|
|
LbFormat: TListBox;
|
|
Panel1: TPanel;
|
|
Panel2: TPanel;
|
|
EdDecimals: TSpinEdit;
|
|
CurrSymbolPanel: TPanel;
|
|
BtnAddCurrSymbol: TSpeedButton;
|
|
Shape1: TShape;
|
|
BtnAddFormat: TSpeedButton;
|
|
BtnDeleteFormat: TSpeedButton;
|
|
procedure BtnAddCurrSymbolClick(Sender: TObject);
|
|
procedure BtnAddFormatClick(Sender: TObject);
|
|
procedure BtnDeleteFormatClick(Sender: TObject);
|
|
procedure CbCurrSymbolSelect(Sender: TObject);
|
|
procedure CbNegRedClick(Sender: TObject);
|
|
procedure CbThousandSepClick(Sender: TObject);
|
|
procedure EdDecimalsChange(Sender: TObject);
|
|
procedure EdNumFormatStrChange(Sender: TObject);
|
|
procedure LbCategoryClick(Sender: TObject);
|
|
procedure LbFormatClick(Sender: TObject);
|
|
procedure LbFormatDrawItem(Control: TWinControl; Index: Integer;
|
|
ARect: TRect; State: TOwnerDrawState);
|
|
private
|
|
{ private declarations }
|
|
FWorkbook: TsWorkbook;
|
|
FSampleValue: Double;
|
|
FSampleText: String;
|
|
FGenerator: array[TsNumFormatCategory] of Double;
|
|
FNumFormatStrOfList: String;
|
|
FLockCount: Integer;
|
|
function GetNumFormatStr: String;
|
|
procedure SetNumFormatStr(const AValue: String);
|
|
protected
|
|
function FindNumFormat(ACategory: TsNumFormatCategory;
|
|
ANumFormatStr: String): Integer;
|
|
function FormatStrOfListIndex(AIndex: Integer): String;
|
|
procedure ReplaceCurrSymbol;
|
|
procedure ReplaceDecs;
|
|
procedure SelectCategory(ACategory: TsNumFormatCategory);
|
|
procedure SelectFormat(AIndex: Integer);
|
|
procedure UpdateControls(ANumFormatParams: TsNumFormatParams);
|
|
procedure UpdateSample(ANumFormatParams: TsNumFormatParams);
|
|
public
|
|
{ public declarations }
|
|
constructor Create(AOwner: TComponent); override;
|
|
procedure SetData(ANumFormatStr: String; AWorkbook: TsWorkbook;
|
|
ASample: variant);
|
|
property NumFormatStr: String read GetNumFormatStr;
|
|
end;
|
|
|
|
var
|
|
NumFormatForm: TNumFormatForm;
|
|
|
|
procedure ReadNumFormatsFromIni(const AIniFile: TCustomIniFile);
|
|
procedure WriteNumFormatsToIni(const AIniFile: TCustomIniFile);
|
|
|
|
implementation
|
|
|
|
{$R *.lfm}
|
|
|
|
uses
|
|
LCLType, Math, DateUtils, TypInfo, variants,
|
|
fpsUtils, fpsCurrency,
|
|
sCurrencyForm;
|
|
|
|
const
|
|
BUILTIN_OFFSET = 1;
|
|
USER_OFFSET = 1000;
|
|
|
|
var
|
|
NumFormats: TStringList = nil;
|
|
|
|
procedure AddToList(ACategory: TsNumFormatCategory; AFormatStr: String;
|
|
AOffset: Integer = BUILTIN_OFFSET);
|
|
begin
|
|
if NumFormats.IndexOf(AFormatStr) = -1 then
|
|
NumFormats.AddObject(AFormatStr, TObject(PtrInt(AOffset + ord(ACategory))));
|
|
end;
|
|
|
|
procedure InitNumFormats(AFormatSettings: TFormatSettings);
|
|
var
|
|
copiedFormats: TStringList;
|
|
nfs: String;
|
|
data: PtrInt;
|
|
i: Integer;
|
|
fs: TFormatSettings absolute AFormatSettings;
|
|
begin
|
|
copiedFormats := nil;
|
|
|
|
// Store user-defined formats already added to NumFormats list
|
|
if NumFormats <> nil then
|
|
begin
|
|
copiedFormats := TStringList.Create;
|
|
for i:=0 to NumFormats.Count-1 do
|
|
begin
|
|
nfs := NumFormats.Strings[i];
|
|
data := PtrInt(NumFormats.Objects[i]);
|
|
if data >= USER_OFFSET then
|
|
copiedFormats.AddObject(nfs, TObject(data));
|
|
end;
|
|
NumFormats.Free;
|
|
end;
|
|
|
|
NumFormats := TStringList.Create;
|
|
|
|
// Add built-in formats
|
|
AddToList(nfcNumber, 'General');
|
|
AddToList(nfcNumber, '0');
|
|
AddToList(nfcNumber, '0.0');
|
|
AddToList(nfcNumber, '0.00');
|
|
AddToList(nfcNumber, '0.000');
|
|
AddToList(nfcNumber, '#,##0');
|
|
AddToList(nfcNumber, '#,##0.0');
|
|
AddToList(nfcNumber, '#,##0.00');
|
|
AddToList(nfcNumber, '#,##0.000');
|
|
|
|
AddToList(nfcPercent, '0%');
|
|
AddToList(nfcPercent, '0.0%');
|
|
AddToList(nfcPercent, '0.00%');
|
|
AddToList(nfcPercent, '0.000%');
|
|
|
|
AddToList(nfcScientific, '0E+0');
|
|
AddToList(nfcScientific, '0E+00');
|
|
AddToList(nfcScientific, '0E+000');
|
|
AddToList(nfcScientific, '0.0E+0');
|
|
AddToList(nfcScientific, '0.0E+00');
|
|
AddToList(nfcScientific, '0.0E+000');
|
|
AddToList(nfcScientific, '0.00E+0');
|
|
AddToList(nfcScientific, '0.00E+00');
|
|
AddToList(nfcScientific, '0.00E+000');
|
|
AddToList(nfcScientific, '0.000E+0');
|
|
AddToList(nfcScientific, '0.000E+00');
|
|
AddToList(nfcScientific, '0.000E+000');
|
|
AddToList(nfcScientific, '0E-0');
|
|
AddToList(nfcScientific, '0E-00');
|
|
AddToList(nfcScientific, '0E-000');
|
|
AddToList(nfcScientific, '0.0E-0');
|
|
AddToList(nfcScientific, '0.0E-00');
|
|
AddToList(nfcScientific, '0.0E-000');
|
|
AddToList(nfcScientific, '0.00E-0');
|
|
AddToList(nfcScientific, '0.00E-00');
|
|
AddToList(nfcScientific, '0.00E-000');
|
|
AddToList(nfcScientific, '0.000E-0');
|
|
AddToList(nfcScientific, '0.000E-00');
|
|
AddToList(nfcScientific, '0.000E-000');
|
|
|
|
AddToList(nfcFraction, '# ?/?');
|
|
AddToList(nfcFraction, '# ??/??');
|
|
AddToList(nfcFraction, '# ???/???');
|
|
AddToList(nfcFraction, '# ?/2');
|
|
AddToList(nfcFraction, '# ?/4');
|
|
AddToList(nfcFraction, '# ?/8');
|
|
AddToList(nfcFraction, '# ?/16');
|
|
AddToList(nfcFraction, '# ?/32');
|
|
AddToList(nfcFraction, '?/?');
|
|
AddToList(nfcFraction, '?/??');
|
|
AddToList(nfcFraction, '?/???');
|
|
AddToList(nfcFraction, '?/2');
|
|
AddToList(nfcFraction, '?/4');
|
|
AddToList(nfcFraction, '?/8');
|
|
AddToList(nfcFraction, '?/16');
|
|
AddToList(nfcFraction, '?/32');
|
|
|
|
AddToList(nfcCurrency, '#,##0 [$$];-#,##0 [$$]');
|
|
AddToList(nfcCurrency, '#,##0.00 [$$];-#,##0.00 [$$]');
|
|
AddToList(nfcCurrency, '#,##0 [$$];(#,##0) [$$]');
|
|
AddToList(nfcCurrency, '#,##0.00 [$$];(#,##0.00) [$$]');
|
|
AddToList(nfcCurrency, '#,##0 [$$];[red]-#,##0 [$$]');
|
|
AddToList(nfcCurrency, '#,##0.00 [$$];[red]-#,##0.00 [$$]');
|
|
AddToList(nfcCurrency, '#,##0 [$$];[red](#,##0) [$$]');
|
|
AddToList(nfcCurrency, '#,##0.00 [$$];[red]-#,##0.00 [$$]');
|
|
AddToList(nfcCurrency, '[$$] #,##0;[$$] -#,##0');
|
|
AddToList(nfcCurrency, '[$$] #,##0.00;[$$] -#,##0.00');
|
|
AddToList(nfcCurrency, '[$$] #,##0;[$$] (#,##0)');
|
|
AddToList(nfcCurrency, '[$$] #,##0.00;[$$] (#,##0.00)');
|
|
AddToList(nfcCurrency, '[$$] #,##0;[red][$$] -#,##0');
|
|
AddToList(nfcCurrency, '[$$] #,##0.00;[red][$$] -#,##0.00');
|
|
AddToList(nfcCurrency, '[$$] #,##0;[red][$$] (#,##0)');
|
|
AddToList(nfcCurrency, '[$$] #,##0.00;[red][$$] -#,##0.00');
|
|
|
|
AddToList(nfcDate, 'dddd, '+fs.LongDateFormat + ' ' + fs.ShortTimeFormat);
|
|
AddToList(nfcDate, 'dddd, '+fs.ShortDateFormat + ' ' + fs.ShortTimeFormat);
|
|
AddToList(nfcDate, 'dddd, '+fs.LongDateFormat);
|
|
AddToList(nfcDate, 'dddd, '+fs.ShortDateFormat);
|
|
AddToList(nfcDate, 'ddd., '+fs.LongDateFormat + ' ' + fs.ShortTimeFormat);
|
|
AddToList(nfcDate, 'ddd., '+fs.ShortDateFormat + ' ' + fs.ShortTimeFormat);
|
|
AddToList(nfcDate, 'ddd., '+fs.LongDateFormat);
|
|
AddToList(nfcDate, 'ddd., '+fs.ShortDateFormat);
|
|
AddToList(nfcDate, fs.LongDateFormat + ' ' + fs.ShortTimeFormat);
|
|
AddToList(nfcDate, fs.ShortDateFormat + ' ' + fs.ShortTimeFormat);
|
|
AddToList(nfcDate, fs.LongDateFormat);
|
|
AddToList(nfcDate, fs.ShortDateFormat);
|
|
AddToList(nfcDate, 'dd. mmmm');
|
|
AddToList(nfcDate, 'dd. mmm.');
|
|
AddToList(nfcDate, 'd. mmmm');
|
|
AddToList(nfcDate, 'd. mmm.');
|
|
AddToList(nfcDate, 'mmmm dd');
|
|
AddToList(nfcDate, 'mmmm d');
|
|
AddToList(nfcDate, 'mmm. dd');
|
|
AddToList(nfcDate, 'mmm. d');
|
|
AddToList(nfcDate, 'mmmm yyyy');
|
|
AddToList(nfcDate, 'mmm. yy');
|
|
AddToList(nfcDate, 'yyyy-mmm');
|
|
AddToList(nfcDate, 'yy-mmm');
|
|
|
|
AddToList(nfcTime, fs.LongTimeFormat);
|
|
AddToList(nfcTime, fs.ShortTimeFormat);
|
|
AddToList(nfcTime, AddAMPM(fs.LongTimeFormat, fs));
|
|
AddToList(nfcTime, AddAMPM(fs.ShortTimeFormat, fs));
|
|
AddToList(nfcTime, 'nn:ss');
|
|
AddToList(nfcTime, 'nn:ss.0');
|
|
AddToList(nfcTime, 'nn:ss.00');
|
|
AddToList(nfcTime, 'nn:ss.000');
|
|
AddToList(nfcTime, '[h]:nn');
|
|
AddToList(nfcTime, '[h]:nn:ss');
|
|
|
|
AddToList(nfcText, '@');
|
|
|
|
// Add user-defined formats
|
|
if copiedFormats <> nil then
|
|
begin
|
|
for i:=0 to copiedFormats.Count-1 do begin
|
|
nfs := copiedFormats.Strings[i];
|
|
data := PtrInt(copiedFormats.Objects[i]);
|
|
NumFormats.AddObject(nfs, TObject(PtrInt(data)));
|
|
end;
|
|
copiedFormats.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure DestroyNumFormats;
|
|
begin
|
|
NumFormats.Free;
|
|
end;
|
|
|
|
{ Reads the user-defined number format strings from an ini file. }
|
|
procedure ReadNumFormatsFromIni(const AIniFile: TCustomIniFile);
|
|
var
|
|
section: String;
|
|
list: TStringList;
|
|
cat: TsNumFormatCategory;
|
|
i: Integer;
|
|
nfs: String;
|
|
scat: String;
|
|
begin
|
|
if NumFormats = nil
|
|
then NumFormats := TStringList.Create
|
|
else NumFormats.Clear;
|
|
|
|
list := TStringList.Create;
|
|
try
|
|
section := 'Built-in number formats';
|
|
AIniFile.ReadSection(section, list);
|
|
for i:=0 to list.Count-1 do begin
|
|
scat := list.Names[i];
|
|
nfs := list.Values[scat];
|
|
cat := TsNumFormatCategory(GetEnumValue(TypeInfo(TsNumFormatCategory), scat));
|
|
AddToList(cat, nfs, BUILTIN_OFFSET);
|
|
end;
|
|
|
|
list.Clear;
|
|
section := 'User-defined number formats';
|
|
AIniFile.ReadSection(section, list);
|
|
for i:=0 to list.Count-1 do begin
|
|
scat := list.Names[i];
|
|
nfs := list.Values[scat];
|
|
cat := TsNumFormatCategory(GetEnumValue(TypeInfo(TsNumFormatCategory), scat));
|
|
AddToList(cat, nfs, USER_OFFSET);
|
|
end;
|
|
|
|
finally
|
|
list.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure WriteNumFormatsToIni(const AIniFile: TCustomIniFile);
|
|
var
|
|
data: PtrInt;
|
|
section: String;
|
|
i: Integer;
|
|
cat: TsNumFormatCategory;
|
|
scat: String;
|
|
nfs: String;
|
|
begin
|
|
section := 'Built-in number formats';
|
|
for i:=0 to NumFormats.Count-1 do
|
|
begin
|
|
data := PtrInt(NumFormats.Objects[i]);
|
|
if data < USER_OFFSET then
|
|
begin
|
|
cat := TsNumFormatCategory(data - BUILTIN_OFFSET);
|
|
scat := Copy(GetEnumName(TypeInfo(TsNumFormatCategory), ord(cat)), 3, MaxInt);
|
|
nfs := NumFormats.Strings[i];
|
|
AIniFile.WriteString(section, scat, nfs);
|
|
end;
|
|
end;
|
|
|
|
section := 'User-defined number formats';
|
|
for i:=0 to NumFormats.Count-1 do
|
|
begin
|
|
data := PtrInt(NumFormats.Objects[i]);
|
|
if data >= USER_OFFSET then
|
|
begin
|
|
cat := TsNumFormatCategory(data - USER_OFFSET);
|
|
scat := Copy(GetEnumName(TypeInfo(TsNumFormatCategory), ord(cat)), 3, MaxInt);
|
|
nfs := NumFormats.Strings[i];
|
|
AIniFile.WriteString(section, scat, nfs);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
{ TNumFormatForm }
|
|
|
|
constructor TNumFormatForm.Create(AOwner: TComponent);
|
|
begin
|
|
inherited Create(AOwner);
|
|
FGenerator[nfcNumber] := -1234.123456;
|
|
FGenerator[nfcPercent] := -0.123456789;
|
|
FGenerator[nfcScientific] := -1234.5678;
|
|
FGenerator[nfcFraction] := -1234; //-1.23456;
|
|
FGenerator[nfcCurrency] := -1234.56789;
|
|
FGenerator[nfcDate] := EncodeDate(YearOf(date), 1, 1);
|
|
FGenerator[nfcTime] := EncodeTime(9, 0, 2, 235);
|
|
FGenerator[nfcText] := NaN;
|
|
GetRegisteredCurrencies(CbCurrSymbol.Items);
|
|
end;
|
|
|
|
procedure TNumFormatForm.BtnAddCurrSymbolClick(Sender: TObject);
|
|
var
|
|
F: TCurrencyForm;
|
|
begin
|
|
F := TCurrencyForm.Create(nil);
|
|
try
|
|
if F.ShowModal = mrOK then
|
|
begin
|
|
GetRegisteredCurrencies(CbCurrSymbol.Items);
|
|
CbCurrSymbol.ItemIndex := CbCurrSymbol.Items.IndexOf(F.CurrencySymbol);
|
|
ReplaceCurrSymbol;
|
|
end;
|
|
finally
|
|
F.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TNumFormatForm.BtnAddFormatClick(Sender: TObject);
|
|
var
|
|
cat: TsNumFormatCategory;
|
|
idx: Integer;
|
|
nfs: String;
|
|
begin
|
|
if LbCategory.ItemIndex > -1 then begin
|
|
cat := TsNumFormatCategory(LbCategory.ItemIndex);
|
|
nfs := EdNumFormatStr.Text;
|
|
if nfs = '' then nfs := 'General';
|
|
if NumFormats.IndexOf(nfs) = -1 then
|
|
begin
|
|
AddToList(cat, nfs, USER_OFFSET);
|
|
SelectCategory(cat); // Rebuilds the "Format" listbox
|
|
idx := FindNumFormat(cat, nfs);
|
|
SelectFormat(idx);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TNumFormatForm.BtnDeleteFormatClick(Sender: TObject);
|
|
var
|
|
cat: TsNumFormatCategory;
|
|
idx: Integer;
|
|
nfs: String;
|
|
n, i: Integer;
|
|
begin
|
|
if LbCategory.ItemIndex > -1 then begin
|
|
// Find in internal template list
|
|
idx := NumFormats.IndexOf(EdNumFormatStr.Text);
|
|
if idx > -1 then begin
|
|
nfs := NumFormats.Strings[idx];
|
|
n := PtrInt(NumFormats.Objects[idx]);
|
|
if n >= USER_OFFSET
|
|
then cat := TsNumFormatCategory(n - USER_OFFSET)
|
|
else cat := TsNumFormatCategory(n - BUILTIN_OFFSET);
|
|
i := FindNumFormat(cat, nfs); // Index in format listbox
|
|
// Delete from internal template list
|
|
NumFormats.Delete(idx);
|
|
|
|
// Rebuild format listbox (without the deleted item)
|
|
SelectCategory(cat);
|
|
if i >= LbFormat.Items.Count
|
|
then SelectFormat(LbFormat.Items.Count-1)
|
|
else SelectFormat(i);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TNumFormatForm.CbCurrSymbolSelect(Sender: TObject);
|
|
begin
|
|
ReplaceCurrSymbol;
|
|
end;
|
|
|
|
procedure TNumFormatForm.CbNegRedClick(Sender: TObject);
|
|
var
|
|
nfs: String;
|
|
nfp: TsNumFormatParams;
|
|
begin
|
|
if FLockCount > 0 then
|
|
exit;
|
|
|
|
if EdNumFormatStr.Text = '' then nfs := 'General' else nfs := EdNumFormatStr.Text;
|
|
nfp := CreateNumFormatParams(nfs, FWorkbook.FormatSettings);
|
|
if nfp <> nil then
|
|
try
|
|
nfp.SetNegativeRed(CbNegRed.Checked);
|
|
EdNumFormatStr.Text := nfp.NumFormatStr;
|
|
SelectCategory(TsNumFormatCategory(LbCategory.ItemIndex)); // to rebuild the format listbox
|
|
UpdateSample(nfp);
|
|
finally
|
|
nfp.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TNumFormatForm.CbThousandSepClick(Sender: TObject);
|
|
var
|
|
nfs: String;
|
|
nfp: TsNumFormatParams;
|
|
begin
|
|
if FLockCount > 0 then
|
|
exit;
|
|
|
|
if EdNumFormatStr.Text = '' then nfs := 'General' else nfs := EdNumFormatStr.Text;
|
|
nfp := CreateNumFormatParams(nfs, FWorkbook.FormatSettings);
|
|
if nfp <> nil then
|
|
try
|
|
nfp.SetThousandSep(CbThousandSep.Checked);
|
|
EdNumFormatStr.Text := nfp.NumFormatStr;
|
|
SelectCategory(TsNumFormatCategory(LbCategory.ItemIndex)); // to rebuild the format listbox
|
|
UpdateSample(nfp);
|
|
finally
|
|
nfp.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TNumFormatForm.EdDecimalsChange(Sender: TObject);
|
|
begin
|
|
if FLockCount > 0 then
|
|
exit;
|
|
ReplaceDecs;
|
|
end;
|
|
|
|
procedure TNumFormatForm.EdNumFormatStrChange(Sender: TObject);
|
|
var
|
|
nfp: TsNumFormatParams;
|
|
begin
|
|
nfp := CreateNumFormatParams(EdNumFormatStr.Text, FWorkbook.FormatSettings);
|
|
try
|
|
UpdateControls(nfp);
|
|
finally
|
|
nfp.Free;
|
|
end;
|
|
end;
|
|
|
|
{ Returns the index of a specific number format string in the format listbox
|
|
shown for a particular category }
|
|
function TNumFormatForm.FindNumFormat(ACategory: TsNumFormatCategory;
|
|
ANumFormatStr: String): Integer;
|
|
var
|
|
i: Integer;
|
|
data: PtrInt;
|
|
cat: TsNumFormatCategory;
|
|
nfs: String;
|
|
begin
|
|
Result := -1;
|
|
if ANumFormatStr = '' then ANumFormatStr := 'General';
|
|
for i := 0 to NumFormats.Count-1 do begin
|
|
nfs := NumFormats.Strings[i];
|
|
data := PtrInt(NumFormats.Objects[i]);
|
|
if data >= USER_OFFSET then
|
|
cat := TsNumFormatCategory(data - USER_OFFSET)
|
|
else
|
|
cat := TsNumFormatCategory(data - BUILTIN_OFFSET);
|
|
if (cat = ACategory) then
|
|
inc(Result);
|
|
if SameText(nfs, ANumFormatStr) then
|
|
exit;
|
|
end;
|
|
end;
|
|
|
|
function TNumFormatForm.FormatStrOfListIndex(AIndex: Integer): String;
|
|
var
|
|
idx: PtrInt;
|
|
begin
|
|
if (AIndex >= 0) and (AIndex < LbFormat.Count) then
|
|
begin
|
|
idx := PtrInt(LbFormat.Items.Objects[AIndex]);
|
|
Result := NumFormats.Strings[idx];
|
|
end else
|
|
Result := '';
|
|
end;
|
|
|
|
function TNumFormatForm.GetNumFormatStr: String;
|
|
begin
|
|
Result := EdNumFormatStr.Text;
|
|
end;
|
|
|
|
procedure TNumFormatForm.LbCategoryClick(Sender: TObject);
|
|
begin
|
|
SelectCategory(TsNumFormatCategory(LbCategory.ItemIndex));
|
|
end;
|
|
|
|
procedure TNumFormatForm.LbFormatClick(Sender: TObject);
|
|
begin
|
|
SelectFormat(LbFormat.ItemIndex);
|
|
end;
|
|
|
|
procedure TNumFormatForm.LbFormatDrawItem(Control: TWinControl; Index: Integer;
|
|
ARect: TRect; State: TOwnerDrawState);
|
|
var
|
|
s: String;
|
|
nfs: String;
|
|
nfp: TsNumFormatParams;
|
|
idx: PtrInt;
|
|
begin
|
|
Unused(Control);
|
|
LbFormat.Canvas.Brush.Color := clWindow;
|
|
LbFormat.Canvas.Font.Assign(LbFormat.Font);
|
|
if State * [odSelected, odFocused] <> [] then
|
|
begin
|
|
LbFormat.Canvas.Font.Color := clHighlightText;
|
|
LbFormat.Canvas.Brush.Color := clHighlight;
|
|
end;
|
|
if (Index > -1) and (Index < LbFormat.Items.Count) then
|
|
begin
|
|
s := LbFormat.Items[Index];
|
|
idx := PtrInt(LbFormat.Items.Objects[Index]);
|
|
nfs := NumFormats.Strings[idx];
|
|
nfp := CreateNumFormatParams(nfs, FWorkbook.FormatSettings);
|
|
try
|
|
if (nfp <> nil) and (Length(nfp.Sections) > 1) and (nfp.Sections[1].Color = scRed) then
|
|
LbFormat.Canvas.Font.Color := clRed;
|
|
finally
|
|
nfp.Free;
|
|
end;
|
|
end else
|
|
s := '';
|
|
LbFormat.Canvas.FillRect(ARect);
|
|
LbFormat.Canvas.TextRect(ARect, ARect.Left+1, ARect.Top+1, s);
|
|
end;
|
|
|
|
procedure TNumFormatForm.ReplaceCurrSymbol;
|
|
var
|
|
cs: String;
|
|
i: Integer;
|
|
nfp: TsNumFormatParams;
|
|
data: PtrInt;
|
|
cat: TsNumFormatCategory;
|
|
begin
|
|
cs := CbCurrSymbol.Items[CbCurrSymbol.ItemIndex];
|
|
for i:=0 to NumFormats.Count-1 do
|
|
begin
|
|
data := PtrInt(NumFormats.Objects[i]);
|
|
if (data >= USER_OFFSET) then
|
|
cat := TsNumFormatCategory(data - USER_OFFSET)
|
|
else
|
|
cat := TsNumFormatCategory(data - BUILTIN_OFFSET);
|
|
if cat = nfcCurrency then
|
|
begin
|
|
nfp := CreateNumFormatParams(NumFormats.Strings[i], FWorkbook.FormatSettings);
|
|
if (nfp <> nil) then
|
|
try
|
|
nfp.SetCurrSymbol(cs);
|
|
finally
|
|
nfp.Free;
|
|
end;
|
|
end;
|
|
end;
|
|
SelectCategory(TsNumFormatCategory(LbCategory.ItemIndex)); // to rebuild the format listbox
|
|
end;
|
|
|
|
procedure TNumFormatForm.ReplaceDecs;
|
|
var
|
|
nfp: TsNumFormatParams;
|
|
begin
|
|
if EdDecimals.Text = '' then
|
|
exit;
|
|
|
|
nfp := CreateNumFormatParams(EdNumFormatStr.Text, FWorkbook.FormatSettings);
|
|
try
|
|
nfp.SetDecimals(EdDecimals.Value);
|
|
EdNumFormatStr.Text := nfp.NumFormatStr;
|
|
UpdateSample(nfp);
|
|
finally
|
|
nfp.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TNumFormatForm.SelectCategory(ACategory: TsNumFormatCategory);
|
|
var
|
|
nfp: TsNumFormatParams;
|
|
i, digits, numdigits: Integer;
|
|
data: PtrInt;
|
|
s: String;
|
|
genvalue: Double;
|
|
cat: TsNumFormatCategory;
|
|
begin
|
|
LbCategory.ItemIndex := ord(ACategory);
|
|
with LbFormat.Items do
|
|
begin
|
|
Clear;
|
|
for i:=0 to NumFormats.Count-1 do
|
|
begin
|
|
data := PtrInt(NumFormats.Objects[i]);
|
|
if data >= USER_OFFSET then
|
|
cat := TsNumFormatCategory(data - USER_OFFSET)
|
|
else
|
|
cat := TsNumFormatCategory(data - BUILTIN_OFFSET);
|
|
if cat = ACategory then
|
|
begin
|
|
nfp := CreateNumFormatParams(NumFormats.Strings[i], FWorkbook.FormatSettings);
|
|
try
|
|
if IsTextFormat(nfp) then
|
|
s := 'abc'
|
|
else
|
|
begin
|
|
genValue := FGenerator[ACategory];
|
|
if nfkTimeInterval in nfp.Sections[0].Kind then
|
|
genvalue := genValue + 1.0;
|
|
if ACategory = nfcFraction then
|
|
begin
|
|
digits := nfp.Sections[0].FracInt;
|
|
numdigits := nfp.Sections[0].FracDenominator;
|
|
genvalue := 1.0 / (IntPower(10, numdigits) - 3);
|
|
if digits <> 0 then genvalue := -(1234 + genValue);
|
|
end;
|
|
s := ConvertFloatToStr(genValue, nfp, FWorkbook.FormatSettings);
|
|
if s = '' then s := 'General';
|
|
end;
|
|
LbFormat.Items.AddObject(s, TObject(PtrInt(i)));
|
|
finally
|
|
nfp.Free;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
CurrSymbolPanel.Visible := (ACategory = nfcCurrency);
|
|
GbOptions.Visible := not (ACategory in [nfcDate, nfcTime]);
|
|
end;
|
|
|
|
procedure TNumFormatForm.SelectFormat(AIndex: Integer);
|
|
var
|
|
nfp: TsNumFormatParams;
|
|
begin
|
|
if LbCategory.ItemIndex = -1 then
|
|
exit;
|
|
|
|
LbFormat.ItemIndex := AIndex;
|
|
if AIndex >= 0 then begin
|
|
FNumFormatStrOfList := NumFormats.Strings[PtrInt(LbFormat.Items.Objects[AIndex])];
|
|
nfp := CreateNumFormatParams(FNumFormatStrOfList, FWorkbook.FormatSettings);
|
|
try
|
|
UpdateControls(nfp);
|
|
finally
|
|
nfp.Free;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TNumFormatForm.SetData(ANumFormatStr: String; AWorkbook: TsWorkbook;
|
|
ASample: variant);
|
|
var
|
|
cs: String;
|
|
begin
|
|
FWorkbook := AWorkbook;
|
|
cs := FWorkbook.FormatSettings.CurrencyString;
|
|
if (cs = '?') or (cs = '') then
|
|
cs := DefaultFormatSettings.CurrencyString;
|
|
CbCurrSymbol.ItemIndex := CbCurrSymbol.Items.IndexOf(cs);
|
|
|
|
if varIsStr(ASample) then
|
|
FSampleText := VarToStr(ASample)
|
|
else
|
|
FSampleValue := ASample;
|
|
InitNumFormats(FWorkbook.FormatSettings);
|
|
SetNumFormatStr(ANumFormatStr);
|
|
end;
|
|
|
|
procedure TNumFormatForm.SetNumFormatStr(const AValue: String);
|
|
var
|
|
nfs: String;
|
|
nfp: TsNumFormatParams;
|
|
cat: TsNumFormatCategory;
|
|
i: Integer;
|
|
begin
|
|
if AValue = '' then
|
|
i := NumFormats.IndexOf('General')
|
|
else
|
|
i := NumFormats.IndexOf(AValue);
|
|
if i = -1 then
|
|
exit;
|
|
|
|
nfs := NumFormats.Strings[i];
|
|
nfp := CreateNumFormatParams(nfs, FWorkbook.FormatSettings);
|
|
try
|
|
if nfkPercent in nfp.Sections[0].Kind then
|
|
cat := nfcPercent
|
|
else
|
|
if nfkExp in nfp.Sections[0].Kind then
|
|
cat := nfcScientific
|
|
else
|
|
if nfkCurrency in nfp.Sections[0].Kind then
|
|
cat := nfcCurrency
|
|
else
|
|
if nfkFraction in nfp.Sections[0].Kind then
|
|
cat := nfcFraction
|
|
else
|
|
if nfkDate in nfp.Sections[0].Kind then
|
|
cat := nfcDate
|
|
else
|
|
if (nfp.Sections[0].Kind * [nfkDate, nfkTime] = [nfkTime]) then
|
|
cat := nfcTime
|
|
else
|
|
cat := nfcNumber;
|
|
SelectCategory(cat);
|
|
SelectFormat(FindNumFormat(cat, AValue));
|
|
UpdateControls(nfp);
|
|
ReplaceCurrSymbol;
|
|
finally
|
|
nfp.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TNumFormatForm.UpdateControls(ANumFormatParams: TsNumFormatParams);
|
|
var
|
|
cs: String;
|
|
i: Integer;
|
|
begin
|
|
if ANumFormatParams = nil then
|
|
begin
|
|
EdNumFormatStr.Text := 'General';
|
|
GbOptions.Hide;
|
|
end else
|
|
begin
|
|
EdNumFormatStr.Text := ANumFormatParams.NumFormatStr;
|
|
if (ANumFormatParams.Sections[0].Kind * [nfkDate, nfkTime] <> []) then
|
|
GbOptions.Hide
|
|
else begin
|
|
GbOptions.Show;
|
|
inc(FLockCount);
|
|
EdDecimals.Value := ANumFormatParams.Sections[0].Decimals;
|
|
CbNegRed.Checked := (Length(ANumFormatParams.Sections) > 1) and
|
|
(ANumFormatParams.Sections[1].Color = scRed);
|
|
CbThousandSep.Checked := nfkHasThSep in ANumFormatParams.Sections[0].Kind;
|
|
dec(FLockCount);
|
|
end;
|
|
if (nfkCurrency in ANumFormatParams.Sections[0].Kind) then
|
|
begin
|
|
cs := ANumFormatParams.Sections[0].CurrencySymbol;
|
|
if cs <> '' then
|
|
begin
|
|
i := CbCurrSymbol.Items.IndexOf(cs);
|
|
if i = -1 then begin
|
|
RegisterCurrency(cs);
|
|
i := CbCurrSymbol.Items.Add(cs);
|
|
end;
|
|
CbCurrSymbol.ItemIndex := i;
|
|
end;
|
|
end;
|
|
end;
|
|
UpdateSample(ANumFormatParams);
|
|
end;
|
|
|
|
procedure TNumFormatForm.UpdateSample(ANumFormatParams: TsNumFormatParams);
|
|
begin
|
|
if (FSampleValue < 0) and
|
|
(Length(ANumFormatParams.Sections) > 1) and
|
|
(ANumFormatParams.Sections[1].Color = scRed)
|
|
then
|
|
Sample.Font.Color := clRed
|
|
else
|
|
Sample.Font.Color := clWindowText;
|
|
|
|
if IsTextFormat(ANumFormatParams) then
|
|
Sample.Caption := ApplyTextFormat(FSampleText, ANumFormatParams)
|
|
else
|
|
Sample.Caption := ConvertFloatToStr(FSampleValue, ANumFormatParams,
|
|
FWorkbook.FormatSettings);
|
|
|
|
BtnAddFormat.Enabled := (EdNumFormatStr.Text <> FNumFormatStrOfList);
|
|
end;
|
|
|
|
|
|
initialization
|
|
|
|
finalization
|
|
DestroyNumFormats;
|
|
|
|
end.
|
|
|