fpspreadsheet: Introduce string encoding when reading/writing csv files. Automatic detection of currency working now (€ symbol is detected correctly now). Use UTF8 encoded format settings.
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@3687 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
parent
391cd0a647
commit
c4d1e08656
@ -10,11 +10,11 @@ object CSVParamsForm: TCSVParamsForm
|
||||
OnCloseQuery = FormCloseQuery
|
||||
OnCreate = FormCreate
|
||||
Position = poMainFormCenter
|
||||
LCLVersion = '1.2.6.0'
|
||||
LCLVersion = '1.3'
|
||||
object ButtonPanel: TButtonPanel
|
||||
Left = 6
|
||||
Height = 38
|
||||
Top = 511
|
||||
Height = 34
|
||||
Top = 515
|
||||
Width = 458
|
||||
OKButton.Name = 'OKButton'
|
||||
OKButton.DefaultCaption = True
|
||||
@ -29,19 +29,19 @@ object CSVParamsForm: TCSVParamsForm
|
||||
end
|
||||
object PageControl: TPageControl
|
||||
Left = 8
|
||||
Height = 495
|
||||
Height = 499
|
||||
Top = 8
|
||||
Width = 454
|
||||
ActivePage = PgDateTimeParams
|
||||
ActivePage = PgGeneralParams
|
||||
Align = alClient
|
||||
BorderSpacing.Around = 8
|
||||
MultiLine = True
|
||||
TabIndex = 3
|
||||
TabIndex = 0
|
||||
TabOrder = 1
|
||||
Options = [nboMultiLine]
|
||||
object PgGeneralParams: TTabSheet
|
||||
Caption = 'General'
|
||||
ClientHeight = 410
|
||||
ClientHeight = 471
|
||||
ClientWidth = 446
|
||||
object LblQuoteChar: TLabel
|
||||
Left = 16
|
||||
@ -54,10 +54,10 @@ object CSVParamsForm: TCSVParamsForm
|
||||
end
|
||||
object CbQuoteChar: TComboBox
|
||||
Left = 156
|
||||
Height = 28
|
||||
Height = 23
|
||||
Top = 80
|
||||
Width = 155
|
||||
ItemHeight = 20
|
||||
Width = 275
|
||||
ItemHeight = 15
|
||||
ItemIndex = 0
|
||||
Items.Strings = (
|
||||
'none'
|
||||
@ -70,10 +70,10 @@ object CSVParamsForm: TCSVParamsForm
|
||||
end
|
||||
object CbDelimiter: TComboBox
|
||||
Left = 156
|
||||
Height = 28
|
||||
Height = 23
|
||||
Top = 16
|
||||
Width = 155
|
||||
ItemHeight = 20
|
||||
Width = 275
|
||||
ItemHeight = 15
|
||||
ItemIndex = 4
|
||||
Items.Strings = (
|
||||
'Comma ( , )'
|
||||
@ -106,10 +106,10 @@ object CSVParamsForm: TCSVParamsForm
|
||||
end
|
||||
object CbLineEnding: TComboBox
|
||||
Left = 156
|
||||
Height = 28
|
||||
Height = 23
|
||||
Top = 48
|
||||
Width = 155
|
||||
ItemHeight = 20
|
||||
Width = 275
|
||||
ItemHeight = 15
|
||||
ItemIndex = 0
|
||||
Items.Strings = (
|
||||
'System'
|
||||
@ -122,10 +122,10 @@ object CSVParamsForm: TCSVParamsForm
|
||||
Text = 'System'
|
||||
end
|
||||
object RgDetectContentType: TRadioGroup
|
||||
Left = 19
|
||||
Left = 16
|
||||
Height = 80
|
||||
Top = 128
|
||||
Width = 292
|
||||
Top = 156
|
||||
Width = 415
|
||||
AutoFill = True
|
||||
Caption = 'Conversion of strings after reading'
|
||||
ChildSizing.LeftRightSpacing = 6
|
||||
@ -135,8 +135,8 @@ object CSVParamsForm: TCSVParamsForm
|
||||
ChildSizing.ShrinkVertical = crsScaleChilds
|
||||
ChildSizing.Layout = cclLeftToRightThenTopToBottom
|
||||
ChildSizing.ControlsPerLine = 1
|
||||
ClientHeight = 58
|
||||
ClientWidth = 288
|
||||
ClientHeight = 60
|
||||
ClientWidth = 411
|
||||
ItemIndex = 1
|
||||
Items.Strings = (
|
||||
'Do not convert, strings are sufficient'
|
||||
@ -144,16 +144,35 @@ object CSVParamsForm: TCSVParamsForm
|
||||
)
|
||||
TabOrder = 3
|
||||
end
|
||||
object LbEncoding: TLabel
|
||||
Left = 16
|
||||
Height = 15
|
||||
Top = 116
|
||||
Width = 87
|
||||
Caption = 'String encoding:'
|
||||
FocusControl = CbEncoding
|
||||
ParentColor = False
|
||||
end
|
||||
object CbEncoding: TComboBox
|
||||
Left = 156
|
||||
Height = 23
|
||||
Top = 112
|
||||
Width = 275
|
||||
DropDownCount = 32
|
||||
ItemHeight = 15
|
||||
Style = csDropDownList
|
||||
TabOrder = 4
|
||||
end
|
||||
end
|
||||
object PgNumberParams: TTabSheet
|
||||
Caption = 'Number cells'
|
||||
ClientHeight = 410
|
||||
ClientHeight = 471
|
||||
ClientWidth = 446
|
||||
object CbAutoDetectNumberFormat: TCheckBox
|
||||
Left = 16
|
||||
Height = 24
|
||||
Height = 19
|
||||
Top = 16
|
||||
Width = 248
|
||||
Width = 200
|
||||
Caption = 'Try to auto-detect number format'
|
||||
Checked = True
|
||||
State = cbChecked
|
||||
@ -161,16 +180,16 @@ object CSVParamsForm: TCSVParamsForm
|
||||
end
|
||||
object EdNumFormat: TEdit
|
||||
Left = 232
|
||||
Height = 28
|
||||
Height = 23
|
||||
Top = 140
|
||||
Width = 194
|
||||
TabOrder = 3
|
||||
end
|
||||
object LblNumFormat: TLabel
|
||||
Left = 17
|
||||
Height = 20
|
||||
Height = 15
|
||||
Top = 144
|
||||
Width = 225
|
||||
Width = 182
|
||||
Caption = 'Format string for writing numbers:'
|
||||
FocusControl = EdNumFormat
|
||||
ParentColor = False
|
||||
@ -191,23 +210,23 @@ object CSVParamsForm: TCSVParamsForm
|
||||
end
|
||||
object LblDecimalSeparator: TLabel
|
||||
Left = 16
|
||||
Height = 20
|
||||
Height = 15
|
||||
Top = 59
|
||||
Width = 125
|
||||
Width = 98
|
||||
Caption = 'Decimal separator:'
|
||||
FocusControl = CbDecimalSeparator
|
||||
ParentColor = False
|
||||
end
|
||||
object CbDecimalSeparator: TComboBox
|
||||
Left = 232
|
||||
Height = 28
|
||||
Height = 23
|
||||
Top = 56
|
||||
Width = 194
|
||||
ItemHeight = 20
|
||||
ItemHeight = 15
|
||||
ItemIndex = 0
|
||||
Items.Strings = (
|
||||
'like spreadsheet'
|
||||
'Dot ( . )'
|
||||
'Period ( . )'
|
||||
'Comma ( , )'
|
||||
)
|
||||
TabOrder = 1
|
||||
@ -215,23 +234,23 @@ object CSVParamsForm: TCSVParamsForm
|
||||
end
|
||||
object LblThousandSeparator: TLabel
|
||||
Left = 16
|
||||
Height = 20
|
||||
Height = 15
|
||||
Top = 91
|
||||
Width = 134
|
||||
Width = 108
|
||||
Caption = 'Thousand separator:'
|
||||
FocusControl = CbThousandSeparator
|
||||
ParentColor = False
|
||||
end
|
||||
object CbThousandSeparator: TComboBox
|
||||
Left = 232
|
||||
Height = 28
|
||||
Height = 23
|
||||
Top = 88
|
||||
Width = 194
|
||||
ItemHeight = 20
|
||||
ItemHeight = 15
|
||||
ItemIndex = 0
|
||||
Items.Strings = (
|
||||
'like spreadsheet'
|
||||
'Dot ( . )'
|
||||
'Period ( . )'
|
||||
'Comma ( , )'
|
||||
'Space ( )'
|
||||
)
|
||||
@ -241,20 +260,20 @@ object CSVParamsForm: TCSVParamsForm
|
||||
end
|
||||
object PgCurrency: TTabSheet
|
||||
Caption = 'Currency cells'
|
||||
ClientHeight = 410
|
||||
ClientHeight = 471
|
||||
ClientWidth = 446
|
||||
object LblCurrencySymbol: TLabel
|
||||
Left = 16
|
||||
Height = 20
|
||||
Height = 15
|
||||
Top = 20
|
||||
Width = 112
|
||||
Width = 93
|
||||
Caption = 'Currency symbol:'
|
||||
FocusControl = EdCurrencySymbol
|
||||
ParentColor = False
|
||||
end
|
||||
object EdCurrencySymbol: TEdit
|
||||
Left = 232
|
||||
Height = 28
|
||||
Height = 23
|
||||
Top = 16
|
||||
Width = 194
|
||||
OnEnter = DateTimeFormatChange
|
||||
@ -264,39 +283,39 @@ object CSVParamsForm: TCSVParamsForm
|
||||
end
|
||||
object PgDateTimeParams: TTabSheet
|
||||
Caption = 'Date/time cells'
|
||||
ClientHeight = 437
|
||||
ClientHeight = 471
|
||||
ClientWidth = 446
|
||||
object LblNumFormat1: TLabel
|
||||
Left = 16
|
||||
Height = 20
|
||||
Height = 15
|
||||
Top = 20
|
||||
Width = 160
|
||||
Width = 128
|
||||
Caption = 'Long date format string:'
|
||||
ParentColor = False
|
||||
end
|
||||
object LblNumFormat2: TLabel
|
||||
Left = 16
|
||||
Height = 20
|
||||
Height = 15
|
||||
Top = 52
|
||||
Width = 162
|
||||
Width = 129
|
||||
Caption = 'Short date format string:'
|
||||
ParentColor = False
|
||||
end
|
||||
object LblDecimalSeparator1: TLabel
|
||||
Left = 16
|
||||
Height = 20
|
||||
Height = 15
|
||||
Top = 83
|
||||
Width = 102
|
||||
Width = 79
|
||||
Caption = 'Date separator:'
|
||||
FocusControl = CbDateSeparator
|
||||
ParentColor = False
|
||||
end
|
||||
object CbDateSeparator: TComboBox
|
||||
Left = 232
|
||||
Height = 28
|
||||
Height = 23
|
||||
Top = 80
|
||||
Width = 194
|
||||
ItemHeight = 20
|
||||
ItemHeight = 15
|
||||
ItemIndex = 0
|
||||
Items.Strings = (
|
||||
'like spreadsheet'
|
||||
@ -311,35 +330,35 @@ object CSVParamsForm: TCSVParamsForm
|
||||
end
|
||||
object LblNumFormat3: TLabel
|
||||
Left = 16
|
||||
Height = 20
|
||||
Height = 15
|
||||
Top = 268
|
||||
Width = 160
|
||||
Width = 129
|
||||
Caption = 'Long time format string:'
|
||||
ParentColor = False
|
||||
end
|
||||
object LblNumFormat4: TLabel
|
||||
Left = 16
|
||||
Height = 20
|
||||
Height = 15
|
||||
Top = 300
|
||||
Width = 162
|
||||
Width = 130
|
||||
Caption = 'Short time format string:'
|
||||
ParentColor = False
|
||||
end
|
||||
object LblDecimalSeparator2: TLabel
|
||||
Left = 16
|
||||
Height = 20
|
||||
Height = 15
|
||||
Top = 331
|
||||
Width = 103
|
||||
Width = 82
|
||||
Caption = 'Time separator:'
|
||||
FocusControl = CbTimeSeparator
|
||||
ParentColor = False
|
||||
end
|
||||
object CbTimeSeparator: TComboBox
|
||||
Left = 232
|
||||
Height = 28
|
||||
Height = 23
|
||||
Top = 328
|
||||
Width = 194
|
||||
ItemHeight = 20
|
||||
ItemHeight = 15
|
||||
ItemIndex = 0
|
||||
Items.Strings = (
|
||||
'like spreadsheet'
|
||||
@ -355,42 +374,42 @@ object CSVParamsForm: TCSVParamsForm
|
||||
end
|
||||
object LblLongMonthNames: TLabel
|
||||
Left = 16
|
||||
Height = 20
|
||||
Height = 15
|
||||
Top = 116
|
||||
Width = 130
|
||||
Width = 107
|
||||
Caption = 'Long month names:'
|
||||
ParentColor = False
|
||||
end
|
||||
object LblShortMonthNames: TLabel
|
||||
Left = 16
|
||||
Height = 20
|
||||
Height = 15
|
||||
Top = 148
|
||||
Width = 132
|
||||
Width = 108
|
||||
Caption = 'Short month names:'
|
||||
ParentColor = False
|
||||
end
|
||||
object LblLongDayNames: TLabel
|
||||
Left = 16
|
||||
Height = 20
|
||||
Height = 15
|
||||
Top = 180
|
||||
Width = 111
|
||||
Width = 90
|
||||
Caption = 'Long day names:'
|
||||
ParentColor = False
|
||||
end
|
||||
object LblShortDayNames: TLabel
|
||||
Left = 16
|
||||
Height = 20
|
||||
Height = 15
|
||||
Top = 212
|
||||
Width = 113
|
||||
Width = 91
|
||||
Caption = 'Short day names:'
|
||||
ParentColor = False
|
||||
end
|
||||
object CbLongDateFormat: TComboBox
|
||||
Left = 232
|
||||
Height = 28
|
||||
Height = 23
|
||||
Top = 16
|
||||
Width = 194
|
||||
ItemHeight = 20
|
||||
ItemHeight = 15
|
||||
ItemIndex = 0
|
||||
Items.Strings = (
|
||||
'like spreadsheet'
|
||||
@ -416,10 +435,10 @@ object CSVParamsForm: TCSVParamsForm
|
||||
end
|
||||
object CbShortDateFormat: TComboBox
|
||||
Left = 232
|
||||
Height = 28
|
||||
Height = 23
|
||||
Top = 48
|
||||
Width = 194
|
||||
ItemHeight = 20
|
||||
ItemHeight = 15
|
||||
ItemIndex = 0
|
||||
Items.Strings = (
|
||||
'like spreadsheet'
|
||||
@ -440,10 +459,10 @@ object CSVParamsForm: TCSVParamsForm
|
||||
end
|
||||
object CbLongTimeFormat: TComboBox
|
||||
Left = 232
|
||||
Height = 28
|
||||
Height = 23
|
||||
Top = 264
|
||||
Width = 194
|
||||
ItemHeight = 20
|
||||
ItemHeight = 15
|
||||
ItemIndex = 0
|
||||
Items.Strings = (
|
||||
'like spreadsheet'
|
||||
@ -458,10 +477,10 @@ object CSVParamsForm: TCSVParamsForm
|
||||
end
|
||||
object CbShortTimeFormat: TComboBox
|
||||
Left = 232
|
||||
Height = 28
|
||||
Height = 23
|
||||
Top = 296
|
||||
Width = 194
|
||||
ItemHeight = 20
|
||||
ItemHeight = 15
|
||||
ItemIndex = 0
|
||||
Items.Strings = (
|
||||
'like spreadsheet'
|
||||
@ -480,7 +499,7 @@ object CSVParamsForm: TCSVParamsForm
|
||||
Top = 366
|
||||
Width = 409
|
||||
Caption = 'Sample'
|
||||
ClientHeight = 36
|
||||
ClientHeight = 38
|
||||
ClientWidth = 405
|
||||
TabOrder = 6
|
||||
object LblDateTimeSample: TLabel
|
||||
@ -498,7 +517,7 @@ object CSVParamsForm: TCSVParamsForm
|
||||
end
|
||||
object PgBoolParams: TTabSheet
|
||||
Caption = 'Boolean cells'
|
||||
ClientHeight = 410
|
||||
ClientHeight = 471
|
||||
ClientWidth = 446
|
||||
object EdTRUE: TEdit
|
||||
Left = 16
|
||||
|
@ -19,6 +19,7 @@ type
|
||||
CbAutoDetectNumberFormat: TCheckBox;
|
||||
CbLongDateFormat: TComboBox;
|
||||
CbLongTimeFormat: TComboBox;
|
||||
CbEncoding: TComboBox;
|
||||
EdCurrencySymbol: TEdit;
|
||||
CbShortTimeFormat: TComboBox;
|
||||
CbShortDateFormat: TComboBox;
|
||||
@ -42,6 +43,7 @@ type
|
||||
LblDecimalSeparator1: TLabel;
|
||||
LblDecimalSeparator2: TLabel;
|
||||
LblCurrencySymbol: TLabel;
|
||||
LbEncoding: TLabel;
|
||||
LblShortMonthNames: TLabel;
|
||||
LblLongDayNames: TLabel;
|
||||
LblShortDayNames: TLabel;
|
||||
@ -90,16 +92,11 @@ var
|
||||
implementation
|
||||
|
||||
uses
|
||||
fpsUtils;
|
||||
LConvEncoding, fpsUtils;
|
||||
|
||||
resourcestring
|
||||
rsLikeSpreadsheet = 'like spreadsheet';
|
||||
|
||||
{
|
||||
const
|
||||
CURR_VALUE = 100.0;
|
||||
}
|
||||
|
||||
var
|
||||
CSVParamsPageIndex: Integer = 0;
|
||||
|
||||
@ -135,7 +132,7 @@ var
|
||||
arr: Array[1..12] of String;
|
||||
i: Integer;
|
||||
begin
|
||||
fs := DefaultFormatSettings;
|
||||
fs := UTF8FormatSettings;
|
||||
if CbLongDateFormat.ItemIndex <> 0 then
|
||||
fs.LongDateFormat := CbLongDateFormat.Text;
|
||||
if CbShortDateFormat.ItemIndex <> 0 then
|
||||
@ -214,40 +211,44 @@ begin
|
||||
CSVParamsPageIndex := PageControl.ActivePageIndex;
|
||||
end;
|
||||
|
||||
(*
|
||||
procedure TCSVParamsForm.EdCurrencySymbolChange(Sender: TObject);
|
||||
var
|
||||
sel: Integer;
|
||||
begin
|
||||
sel := CbPosCurrencyFormat.ItemIndex;
|
||||
CbPosCurrencyFormat.Items.BeginUpdate;
|
||||
try
|
||||
CbPosCurrencyFormat.Items.Clear;
|
||||
BuildCurrencyFormatList(CbPosCurrencyFormat.Items, true, CURR_VALUE, GetCurrencySymbol);
|
||||
CbPosCurrencyFormat.Items.Insert(0, rsLikeSpreadsheet);
|
||||
CbPosCurrencyFormat.ItemIndex := sel;
|
||||
finally
|
||||
CbPosCurrencyFormat.Items.EndUpdate;
|
||||
end;
|
||||
|
||||
sel := CbNegCurrencyFormat.ItemIndex;
|
||||
CbNegCurrencyFormat.Items.BeginUpdate;
|
||||
try
|
||||
CbNegCurrencyFormat.Items.Clear;
|
||||
BuildCurrencyFormatList(CbNegCurrencyFormat.Items, false, CURR_VALUE, GetCurrencySymbol);
|
||||
CbNegCurrencyFormat.Items.Insert(0, rsLikeSpreadsheet);
|
||||
CbNegCurrencyFormat.ItemIndex := sel;
|
||||
finally
|
||||
CbNegCurrencyFormat.Items.EndUpdate;
|
||||
end;
|
||||
end;
|
||||
*)
|
||||
|
||||
procedure TCSVParamsForm.FormCreate(Sender: TObject);
|
||||
begin
|
||||
PageControl.ActivePageIndex := CSVParamsPageIndex;
|
||||
|
||||
// CbNegCurrencyFormat.DropdownCount := 32;
|
||||
// Populate encoding combobox. Done in code because of the conditional define.
|
||||
with CbEncoding.Items do begin
|
||||
Add('automatic / UTF8');
|
||||
Add('UTF8');
|
||||
Add('UTF8 with BOM');
|
||||
Add('ISO_8859_1 (Central Europe)');
|
||||
Add('ISO_8859_15 (Western European languages)');
|
||||
Add('ISO_8859_2 (Eastern Europe)');
|
||||
Add('CP1250 (Central Europe)');
|
||||
Add('CP1251 (Cyrillic)');
|
||||
Add('CP1252 (Latin 1)');
|
||||
Add('CP1253 (Greek)');
|
||||
Add('CP1254 (Turkish)');
|
||||
Add('CP1255 (Hebrew)');
|
||||
Add('CP1256 (Arabic)');
|
||||
Add('CP1257 (Baltic)');
|
||||
Add('CP1258 (Vietnam)');
|
||||
Add('CP437 (DOS central Europe)');
|
||||
Add('CP850 (DOS western Europe)');
|
||||
Add('CP852 (DOS central Europe)');
|
||||
Add('CP866 (DOS and Windows console''s cyrillic)');
|
||||
Add('CP874 (Thai)');
|
||||
{$IFNDEF DisableAsianCodePages}
|
||||
// Asian encodings
|
||||
Add('CP932 (Japanese)');
|
||||
Add('CP936 (Chinese)');
|
||||
Add('CP949 (Korea)');
|
||||
Add('CP950 (Chinese Complex)');
|
||||
{$ENDIF}
|
||||
Add('KOI8 (Russian cyrillic)');
|
||||
Add('UCS2LE (UCS2-LE 2byte little endian)');
|
||||
Add('UCS2BE (UCS2-BE 2byte big endian)');
|
||||
end;
|
||||
CbEncoding.ItemIndex := 0;
|
||||
|
||||
FEdLongMonthNames := TMonthDayNamesEdit.Create(self);
|
||||
with FEdLongMonthNames do
|
||||
@ -305,12 +306,14 @@ begin
|
||||
end;
|
||||
LblShortDayNames.FocusControl := FEdShortDayNames;
|
||||
|
||||
FDateFormatSample := DefaultFormatSettings.LongDateFormat;
|
||||
FTimeFormatSample := DefaultFormatSettings.LongTimeFormat;
|
||||
FDateFormatSample := UTF8FormatSettings.LongDateFormat;
|
||||
FTimeFormatSample := UTF8FormatSettings.LongTimeFormat;
|
||||
FSampleDateTime := now();
|
||||
end;
|
||||
|
||||
procedure TCSVParamsForm.GetParams(var AParams: TsCSVParams);
|
||||
var
|
||||
s: String;
|
||||
begin
|
||||
// Line endings
|
||||
case CbLineEnding.ItemIndex of
|
||||
@ -336,6 +339,17 @@ begin
|
||||
2: AParams.QuoteChar := '''';
|
||||
end;
|
||||
|
||||
// Encoding
|
||||
if CbEncoding.ItemIndex = 0 then
|
||||
AParams.Encoding := ''
|
||||
else if CbEncoding.ItemIndex = 1 then
|
||||
AParams.Encoding := EncodingUTF8BOM
|
||||
else
|
||||
begin
|
||||
s := CbEncoding.Items[CbEncoding.ItemIndex];
|
||||
AParams.Encoding := Copy(s, 1, Pos(' ', s)-1);
|
||||
end;
|
||||
|
||||
// Detect content type and convert
|
||||
AParams.DetectContentType := RgDetectContentType.ItemIndex <> 0;
|
||||
|
||||
@ -355,7 +369,7 @@ begin
|
||||
if (EdCurrencySymbol.Text = '') or (EdCurrencySymbol.Text = rsLikeSpreadsheet) then
|
||||
AParams.FormatSettings.CurrencyString := ''
|
||||
else
|
||||
AParams.FormatSettings.CurrencyString := UTF8ToAnsi(EdCurrencySymbol.Text);
|
||||
AParams.FormatSettings.CurrencyString := EdCurrencySymbol.Text;
|
||||
|
||||
// Long date format string
|
||||
if (CbLongDateFormat.ItemIndex = 0) or (CbLongDateFormat.Text = '') then
|
||||
@ -407,6 +421,9 @@ begin
|
||||
end;
|
||||
|
||||
procedure TCSVParamsForm.SetParams(const AParams: TsCSVParams);
|
||||
var
|
||||
s: String;
|
||||
i: Integer;
|
||||
begin
|
||||
// Line endings
|
||||
case AParams.LineEnding of
|
||||
@ -432,6 +449,22 @@ begin
|
||||
'''' : CbQuoteChar.ItemIndex := 2;
|
||||
end;
|
||||
|
||||
// String encoding
|
||||
if AParams.Encoding = '' then
|
||||
CbEncoding.ItemIndex := 0
|
||||
else if AParams.Encoding = EncodingUTF8BOM then
|
||||
CbEncoding.ItemIndex := 1
|
||||
else
|
||||
for i:=1 to CbEncoding.Items.Count-1 do
|
||||
begin
|
||||
s := CbEncoding.Items[i];
|
||||
if SameText(AParams.Encoding, Copy(s, 1, Pos(' ', s)-1)) then
|
||||
begin
|
||||
CbEncoding.ItemIndex := i;
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
|
||||
// Detect content type
|
||||
RgDetectContentType.ItemIndex := ord(AParams.DetectContentType);
|
||||
|
||||
@ -462,7 +495,7 @@ begin
|
||||
if AParams.FormatSettings.CurrencyString = '' then
|
||||
EdCurrencySymbol.Text := rsLikeSpreadsheet
|
||||
else
|
||||
EdCurrencySymbol.Text := AnsiToUTF8(AParams.FormatSettings.CurrencyString);
|
||||
EdCurrencySymbol.Text := AParams.FormatSettings.CurrencyString;
|
||||
|
||||
// Long date format
|
||||
if AParams.FormatSettings.LongDateFormat = '' then
|
||||
|
@ -171,7 +171,7 @@ begin
|
||||
L.DelimitedText := Text;
|
||||
for i:=0 to L.Count-1 do
|
||||
if i < L.Count then
|
||||
TMonthNameArray(ANamesArray)[i+1] := UTF8ToAnsi(L[i]);
|
||||
TMonthNameArray(ANamesArray)[i+1] := L[i];
|
||||
finally
|
||||
L.Free;
|
||||
end;
|
||||
@ -189,8 +189,8 @@ begin
|
||||
FShortNames := IsShortNames;
|
||||
|
||||
case FCount of
|
||||
7 : Text := AnsiToUTF8(DayNamesToString(TWeekNameArray(ANamesArray), AEmptyString));
|
||||
12: Text := AnsiToUTF8(MonthNamesToString(TMonthNameArray(ANamesArray), AEmptyString));
|
||||
7: Text := DayNamesToString(TWeekNameArray(ANamesArray), AEmptyString);
|
||||
12: Text := MonthNamesToString(TMonthNameArray(ANamesArray), AEmptyString);
|
||||
else raise Exception.Create('[TMonthDayNameEdit] Array length can only be 7 or 12.');
|
||||
end;
|
||||
end;
|
||||
|
@ -106,39 +106,39 @@ begin
|
||||
if (ctrl = CbLongDateFormat) then
|
||||
begin
|
||||
FDateFormatSample := fs.LongDateFormat;
|
||||
s := AnsiToUTF8(FormatDateTime(FDateFormatSample, dt, fs));
|
||||
s := FormatDateTime(FDateFormatSample, dt, fs);
|
||||
LblDateTimeSample.Caption := 'Sample date:'#13 + s;
|
||||
end
|
||||
else
|
||||
if (ctrl = CbShortDateFormat) then
|
||||
begin
|
||||
FDateFormatSample := fs.ShortDateFormat;
|
||||
s := AnsiToUTF8(FormatDateTime(FDateFormatSample, dt, fs));
|
||||
s := FormatDateTime(FDateFormatSample, dt, fs);
|
||||
LblDateTimeSample.Caption := 'Sample date:'#13 + s;
|
||||
end
|
||||
else
|
||||
if (ctrl = FCbDateSeparator) then begin
|
||||
s := AnsiToUTF8(FormatDateTime(FDateFormatSample, dt, fs));
|
||||
s := FormatDateTime(FDateFormatSample, dt, fs);
|
||||
LblDateTimeSample.Caption := 'Sample date:'#13 + s;
|
||||
end
|
||||
else
|
||||
if (ctrl = CbLongTimeFormat) then
|
||||
begin
|
||||
FTimeFormatSample := fs.LongTimeFormat;
|
||||
s := AnsiToUTF8(FormatDateTime(FTimeFormatSample, dt, fs));
|
||||
s := FormatDateTime(FTimeFormatSample, dt, fs);
|
||||
LblDateTimeSample.Caption := 'Sample time:'#13 + s;
|
||||
end
|
||||
else
|
||||
if (ctrl = CbShortTimeFormat) then
|
||||
begin
|
||||
FTimeFormatSample := fs.ShortTimeFormat;
|
||||
s := AnsiToUTF8(FormatDateTime(FTimeFormatSample, dt, fs));
|
||||
s := FormatDateTime(FTimeFormatSample, dt, fs);
|
||||
LblDateTimeSample.Caption := 'Sample time:'#13 + s;
|
||||
end
|
||||
else
|
||||
if (ctrl = FCbTimeSeparator) then
|
||||
begin
|
||||
s := AnsiToUTF8(FormatDateTime(FTimeFormatSample, dt, fs));
|
||||
s := FormatDateTime(FTimeFormatSample, dt, fs);
|
||||
LblDateTimeSample.Caption := 'Sample time:'#13 + s;
|
||||
{
|
||||
end
|
||||
@ -337,7 +337,7 @@ begin
|
||||
|
||||
// --- Currency format parameters ---
|
||||
// Currency symbol
|
||||
Result.CurrencyString := UTF8ToAnsi(EdCurrencySymbol.Text);
|
||||
Result.CurrencyString := EdCurrencySymbol.Text;
|
||||
// Currency decimal places
|
||||
Result.CurrencyDecimals := EdCurrencyDecimals.Value;
|
||||
// Positive currency format
|
||||
@ -380,7 +380,7 @@ begin
|
||||
|
||||
// --- Currency format parameters ---
|
||||
// Currency symbol
|
||||
EdCurrencySymbol.Text := AnsiToUTF8(AValue.CurrencyString);
|
||||
EdCurrencySymbol.Text := AValue.CurrencyString;
|
||||
// Currency decimal places
|
||||
EdCurrencyDecimals.Value := AValue.CurrencyDecimals;
|
||||
// Positive currency format
|
||||
|
@ -33,7 +33,7 @@ type
|
||||
TsCSVWriter = class(TsCustomSpreadWriter)
|
||||
private
|
||||
FCSVBuilder: TCSVBuilder;
|
||||
FLineEnding: String;
|
||||
FEncoding: String;
|
||||
protected
|
||||
procedure WriteBlank(AStream: TStream; const ARow, ACol: Cardinal;
|
||||
ACell: PCell); override;
|
||||
@ -62,6 +62,7 @@ type
|
||||
LineEnding: TsCSVLineEnding; // W: Specification for line ending to be written
|
||||
Delimiter: Char; // RW: Column delimiter
|
||||
QuoteChar: Char; // RW: Character for quoting texts
|
||||
Encoding: String; // RW: Encoding of file
|
||||
DetectContentType: Boolean; // R: try to convert strings to content types
|
||||
NumberFormat: String; // W: if empty write numbers like in sheet, otherwise use this format
|
||||
AutoDetectNumberFormat: Boolean; // R: automatically detects decimal/thousand separator used in numbers
|
||||
@ -76,6 +77,7 @@ var
|
||||
LineEnding: leSystem;
|
||||
Delimiter: ';';
|
||||
QuoteChar: '"';
|
||||
Encoding: ''; // '' = auto-detect when reading, UTF8 when writing
|
||||
DetectContentType: true;
|
||||
NumberFormat: '';
|
||||
AutoDetectNumberFormat: true;
|
||||
@ -89,7 +91,7 @@ function LineEndingAsString(ALineEnding: TsCSVLineEnding): String;
|
||||
implementation
|
||||
|
||||
uses
|
||||
StrUtils, DateUtils, fpsutils;
|
||||
StrUtils, DateUtils, LConvEncoding, Math, fpsutils;
|
||||
|
||||
{ Initializes the FormatSettings of the CSVParams to default values which
|
||||
can be replaced by the FormatSettings of the workbook's FormatSettings }
|
||||
@ -370,12 +372,12 @@ begin
|
||||
// No idea how to apply the date/time formatsettings here...
|
||||
if IsDateTime(AText, dtValue) then
|
||||
begin
|
||||
if dtValue < 1.0 then // this is a time alone
|
||||
if dtValue < 1.0 then // this is a time alone
|
||||
nf := nfLongTime
|
||||
else
|
||||
if frac(dtValue) = 0.0 then // this is a date alone
|
||||
nf := nfShortDate
|
||||
else // this is date + time
|
||||
else // this is date + time
|
||||
nf := nfShortDateTime;
|
||||
FWorksheet.WriteDateTime(ARow, ACol, dtValue, nf);
|
||||
exit;
|
||||
@ -406,10 +408,23 @@ end;
|
||||
procedure TsCSVReader.ReadFromStream(AStream: TStream; AData: TsWorkbook);
|
||||
var
|
||||
Parser: TCSVParser;
|
||||
s: String;
|
||||
i: Integer;
|
||||
encoding: String;
|
||||
begin
|
||||
// Try to determine encoding of the input file
|
||||
SetLength(s, Min(1000, AStream.Size));
|
||||
AStream.ReadBuffer(s[1], Length(s));
|
||||
if CSVParams.Encoding = '' then
|
||||
encoding := GuessEncoding(s)
|
||||
else
|
||||
encoding := CSVParams.Encoding;
|
||||
|
||||
// Store workbook for internal use, and create worksheet
|
||||
FWorkbook := AData;
|
||||
FWorksheet := AData.AddWorksheet(FWorksheetName);
|
||||
|
||||
// Create csv parser, read file and store in worksheet
|
||||
Parser := TCSVParser.Create;
|
||||
try
|
||||
Parser.Delimiter := CSVParams.Delimiter;
|
||||
@ -418,64 +433,17 @@ begin
|
||||
// Indicate column counts between rows may differ:
|
||||
Parser.EqualColCountPerRow := false;
|
||||
Parser.SetSource(AStream);
|
||||
while Parser.ParseNextCell do
|
||||
ReadCellValue(Parser.CurrentRow, Parser.CurrentCol, Parser.CurrentCellText);
|
||||
|
||||
while Parser.ParseNextCell do begin
|
||||
// Convert string to UTF8
|
||||
s := Parser.CurrentCellText;
|
||||
s := ConvertEncoding(s, encoding, EncodingUTF8);
|
||||
ReadCellValue(Parser.CurrentRow, Parser.CurrentCol, s);
|
||||
end;
|
||||
finally
|
||||
Parser.Free;
|
||||
end;
|
||||
end;
|
||||
{
|
||||
procedure TsCSVReader.ReadFromStream(AStream: TStream; AData: TsWorkbook);
|
||||
var
|
||||
n: Int64;
|
||||
ch: Char;
|
||||
nextch: Char;
|
||||
cellValue: String;
|
||||
r, c: Cardinal;
|
||||
begin
|
||||
FWorkbook := AData;
|
||||
FWorksheet := AData.AddWorksheet(FWorksheetName);
|
||||
n := AStream.Size;
|
||||
cellValue := '';
|
||||
r := 0;
|
||||
c := 0;
|
||||
while AStream.Position < n do begin
|
||||
ch := char(AStream.ReadByte);
|
||||
if (CSVParams.QuoteChar <> #0) and (ch = CSVParams.QuoteChar) then
|
||||
begin
|
||||
// Begin of quoted string --> read until next quote; this allows line breaks
|
||||
// and column separators in quoted string!
|
||||
cellValue := cellValue + ch;
|
||||
repeat
|
||||
ch := char(AStream.ReadByte);
|
||||
cellValue := cellValue + ch;
|
||||
until (AStream.Position = n) or (ch = CSVParams.QuoteChar);
|
||||
end else
|
||||
if ch = CSVParams.Delimiter then begin
|
||||
// End of column reached
|
||||
ReadCellValue(r, c, cellValue);
|
||||
inc(c);
|
||||
cellValue := '';
|
||||
end else
|
||||
if (ch = #13) or (ch = #10) then begin
|
||||
// End of row reached
|
||||
ReadCellValue(r, c, cellValue);
|
||||
inc(r);
|
||||
c := 0;
|
||||
cellValue := '';
|
||||
|
||||
// look for CR+LF: if true, skip next byte
|
||||
if AStream.Position+1 < n then begin
|
||||
nextch := char(AStream.ReadByte);
|
||||
if ((ch = #13) and (nextch <> #10)) then
|
||||
AStream.Position := AStream.Position - 1; // re-read nextchar in next loop
|
||||
end;
|
||||
end else
|
||||
cellValue := cellValue + ch;
|
||||
end;
|
||||
end;
|
||||
}
|
||||
procedure TsCSVReader.ReadFromStrings(AStrings: TStrings; AData: TsWorkbook);
|
||||
var
|
||||
Stream: TStringStream;
|
||||
@ -507,12 +475,10 @@ constructor TsCSVWriter.Create(AWorkbook: TsWorkbook);
|
||||
begin
|
||||
inherited Create(AWorkbook);
|
||||
ReplaceFormatSettings(CSVParams.FormatSettings, FWorkbook.FormatSettings);
|
||||
case CSVParams.LineEnding of
|
||||
leSystem : FLineEnding := LineEnding;
|
||||
leCRLF : FLineEnding := #13#10;
|
||||
leCR : FLineEnding := #13;
|
||||
leLF : FLineEnding := #10;
|
||||
end;
|
||||
if CSVParams.Encoding = '' then
|
||||
FEncoding := 'utf8'
|
||||
else
|
||||
FEncoding := CSVParams.Encoding;
|
||||
end;
|
||||
|
||||
procedure TsCSVWriter.WriteBlank(AStream: TStream; const ARow, ACol: Cardinal;
|
||||
@ -526,29 +492,30 @@ end;
|
||||
{ Write boolean cell to stream formatted as string }
|
||||
procedure TsCSVWriter.WriteBool(AStream: TStream; const ARow, ACol: Cardinal;
|
||||
const AValue: Boolean; ACell: PCell);
|
||||
var
|
||||
s: String;
|
||||
begin
|
||||
Unused(AStream);
|
||||
Unused(ARow, ACol, ACell);
|
||||
if AValue then
|
||||
FCSVBuilder.AppendCell(CSVParams.TrueText)
|
||||
s := CSVParams.TrueText
|
||||
else
|
||||
FCSVBuilder.AppendCell(CSVParams.FalseText);
|
||||
{
|
||||
if AValue then
|
||||
AppendToStream(AStream, CSVParams.TrueText)
|
||||
else
|
||||
AppendToStream(AStream, CSVParams.FalseText);
|
||||
}
|
||||
s := CSVParams.FalseText;
|
||||
s := ConvertEncoding(s, EncodingUTF8, FEncoding);
|
||||
FCSVBuilder.AppendCell(s);
|
||||
end;
|
||||
|
||||
{ Write date/time values in the same way they are displayed in the sheet }
|
||||
procedure TsCSVWriter.WriteDateTime(AStream: TStream; const ARow, ACol: Cardinal;
|
||||
const AValue: TDateTime; ACell: PCell);
|
||||
var
|
||||
s: String;
|
||||
begin
|
||||
Unused(AStream);
|
||||
Unused(ARow, ACol, AValue);
|
||||
FCSVBuilder.AppendCell(FWorksheet.ReadAsUTF8Text(ACell));
|
||||
// AppendToStream(AStream, FWorksheet.ReadAsUTF8Text(ACell));
|
||||
s := FWorksheet.ReadAsUTF8Text(ACell);
|
||||
s := ConvertEncoding(s, EncodingUTF8, FEncoding);
|
||||
FCSVBuilder.AppendCell(s);
|
||||
end;
|
||||
|
||||
{ CSV does not support formulas, but we can write the formula results to
|
||||
@ -579,9 +546,9 @@ begin
|
||||
if ACell = nil then
|
||||
exit;
|
||||
s := ACell^.UTF8StringValue;
|
||||
s := ConvertEncoding(s, EncodingUTF8, FEncoding);
|
||||
// No need to quote; csvdocument will do that for us...
|
||||
FCSVBuilder.AppendCell(s);
|
||||
// AppendToStream(AStream, s);
|
||||
end;
|
||||
|
||||
{ Writes a number cell to the stream. }
|
||||
@ -598,8 +565,8 @@ begin
|
||||
s := Format(CSVParams.NumberFormat, [AValue], CSVParams.FormatSettings)
|
||||
else
|
||||
s := FWorksheet.ReadAsUTF8Text(ACell, CSVParams.FormatSettings);
|
||||
s := ConvertEncoding(s, EncodingUTF8, FEncoding);
|
||||
FCSVBuilder.AppendCell(s);
|
||||
// AppendToStream(AStream, s);
|
||||
end;
|
||||
|
||||
procedure TsCSVWriter.WriteSheet(AStream: TStream; AWorksheet: TsWorksheet);
|
||||
@ -631,18 +598,6 @@ begin
|
||||
finally
|
||||
FreeAndNil(FCSVBuilder);
|
||||
end;
|
||||
{
|
||||
for r := 0 to LastRow do
|
||||
for c := 0 to LastCol do begin
|
||||
Cell := FWorksheet.FindCell(r, c);
|
||||
if Cell <> nil then
|
||||
WriteCellCallback(Cell, AStream);
|
||||
if c = LastCol then
|
||||
AppendToStream(AStream, FLineEnding)
|
||||
else
|
||||
AppendToStream(AStream, CSVParams.Delimiter);
|
||||
end;
|
||||
}
|
||||
end;
|
||||
|
||||
procedure TsCSVWriter.WriteToStream(AStream: TStream);
|
||||
|
@ -908,9 +908,9 @@ type
|
||||
procedure UpdateCaches;
|
||||
|
||||
public
|
||||
{@@ A copy of SysUtil's DefaultFormatSettings to provide some kind of
|
||||
localization to some formatting strings. Can be modified before
|
||||
loading/writing files }
|
||||
{@@ A copy of SysUtil's DefaultFormatSettings (converted to UTF8) to provide
|
||||
some kind of localization to some formatting strings.
|
||||
Can be modified before loading/writing files }
|
||||
FormatSettings: TFormatSettings;
|
||||
|
||||
{ Base methods }
|
||||
@ -5999,7 +5999,7 @@ begin
|
||||
FWorksheets := TFPList.Create;
|
||||
FLog := TStringList.Create;
|
||||
FFormat := sfExcel8;
|
||||
FormatSettings := DefaultFormatSettings;
|
||||
FormatSettings := UTF8FormatSettings;
|
||||
FormatSettings.ShortDateFormat := MakeShortDateFormat(FormatSettings.ShortDateFormat);
|
||||
FormatSettings.LongDateFormat := MakeLongDateFormat(FormatSettings.ShortDateFormat);
|
||||
UseDefaultPalette;
|
||||
|
@ -4,6 +4,8 @@
|
||||
|
||||
// to do: Remove the patched FormatDateTime when the feature of square brackets
|
||||
// in time format codes is in the rtl
|
||||
// to do: Remove the declaration UTF8FormatSettings and InitUTF8FormatSettings
|
||||
// when this same modification is in LazUtils of Laz stable
|
||||
|
||||
unit fpsutils;
|
||||
|
||||
@ -170,6 +172,7 @@ procedure DumpFontsToFile(AWorkbook: TsWorkbook; AFileName: String);
|
||||
|
||||
var
|
||||
ScreenPixelsPerInch: Integer = 96;
|
||||
UTF8FormatSettings: TFormatSettings;
|
||||
|
||||
implementation
|
||||
|
||||
@ -1013,7 +1016,7 @@ begin
|
||||
if (ADecimals < 0) then
|
||||
ADecimals := AFormatSettings.CurrencyDecimals;
|
||||
if ACurrencySymbol = '?' then
|
||||
ACurrencySymbol := AnsiToUTF8(AFormatSettings.CurrencyString); // is this correct? fpspreadsheet should be kept clean of string conversions!
|
||||
ACurrencySymbol := AFormatSettings.CurrencyString;
|
||||
if ACurrencySymbol <> '' then
|
||||
ACurrencySymbol := '"' + ACurrencySymbol + '"';
|
||||
decs := DupeString('0', ADecimals);
|
||||
@ -2641,6 +2644,25 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure InitUTF8FormatSettings;
|
||||
// remove when available in LazUtils
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
UTF8FormatSettings := DefaultFormatSettings;
|
||||
UTF8FormatSettings.CurrencyString := AnsiToUTF8(DefaultFormatSettings.CurrencyString);
|
||||
for i:=1 to 12 do begin
|
||||
UTF8FormatSettings.LongMonthNames[i] := AnsiToUTF8(DefaultFormatSettings.LongMonthNames[i]);
|
||||
UTF8FormatSettings.ShortMonthNames[i] := AnsiToUTF8(DefaultFormatSettings.ShortMonthNames[i]);
|
||||
end;
|
||||
for i:=1 to 7 do begin
|
||||
UTF8FormatSettings.LongDayNames[i] := AnsiToUTF8(DefaultFormatSettings.LongDayNames[i]);
|
||||
UTF8FormatSettings.ShortDayNames[i] := AnsiToUTF8(DefaultFormatSettings.ShortDayNames[i]);
|
||||
end;
|
||||
end;
|
||||
|
||||
initialization
|
||||
InitUTF8FormatSettings;
|
||||
|
||||
end.
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user