unit sFormatsettingsForm; {$mode objfpc}{$H+} interface uses Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs, ButtonPanel, ComCtrls, StdCtrls, Spin, ExtCtrls, Buttons, sCtrls; type { TFormatSettingsForm } TFormatSettingsForm = class(TForm) Bevel1: TBevel; Bevel2: TBevel; Bevel3: TBevel; BtnCurrency: TBitBtn; ButtonPanel: TButtonPanel; CbLongDateFormat: TComboBox; CbLongTimeFormat: TComboBox; CbPosCurrencyFormat: TComboBox; CbNegCurrencyFormat: TComboBox; CbShortDateFormat: TComboBox; CbShortTimeFormat: TComboBox; EdCurrencySymbol: TEdit; EdCurrencyDecimals: TSpinEdit; Label1: TLabel; Label2: TLabel; Label3: TLabel; LblCurrencySymbol: TLabel; LblCurrencySymbol1: TLabel; LblDateTimeSample: TLabel; LblDecimalSeparator: TLabel; LblDateSeparator: TLabel; LblTimeSeparator: TLabel; LblLongDayNames: TLabel; LblLongMonthNames: TLabel; LblNumFormat1: TLabel; LblNumFormat2: TLabel; LblNumFormat3: TLabel; LblNumFormat4: TLabel; LblPosCurrencyFormat: TLabel; LblNegCurrencyFormat: TLabel; LblShortDayNames: TLabel; LblShortMonthNames: TLabel; LblThousandSeparator: TLabel; PageControl: TPageControl; PgCurrency: TTabSheet; PgDateTime: TTabSheet; PgNumber: TTabSheet; procedure BtnCurrencyClick(Sender: TObject); procedure DateTimeFormatChange(Sender: TObject); procedure EdCurrencySymbolChange(Sender: TObject); procedure FormCloseQuery(Sender: TObject; var CanClose: boolean); procedure FormCreate(Sender: TObject); procedure OKButtonClick(Sender: TObject); procedure PageControlChange(Sender: TObject); private FSampleDateTime: TDateTime; FDateFormatSample: String; FTimeFormatSample: String; FEdLongMonthNames: TMonthDayNamesEdit; FEdShortMonthNames: TMonthDayNamesEdit; FEdLongDayNames: TMonthDayNamesEdit; FEdShortDayNames: TMonthDayNamesEdit; FCbDecimalSeparator: TFormatSeparatorCombo; FCbThousandSeparator: TFormatSeparatorCombo; FCbDateSeparator: TFormatSeparatorCombo; FCbTimeSeparator: TFormatSeparatorCombo; function GetFormatSettings: TFormatSettings; procedure SetFormatSettings(const AValue: TFormatSettings); function ValidData(out AControl: TWinControl; out AMsg: String): Boolean; public { public declarations } property FormatSettings: TFormatSettings read GetFormatSettings write SetFormatSettings; end; var FormatSettingsForm: TFormatSettingsForm; implementation {$R *.lfm} uses fpsUtils, fpsNumFormat, sCurrencyForm; const CURR_VALUE = 100.0; var PageIndex: Integer = 0; // stores the previously selected page index (to open the form always with previously used page) { TFormatSettingsForm } procedure TFormatSettingsForm.DateTimeFormatChange(Sender: TObject); var fs: TFormatSettings; ctrl: TWinControl; dt: TDateTime; s: String; begin fs := GetFormatSettings; dt := FSampleDateTime; ctrl := ActiveControl; if (ctrl = CbLongDateFormat) then begin FDateFormatSample := fs.LongDateFormat; s := FormatDateTime(FDateFormatSample, dt, fs); LblDateTimeSample.Caption := 'Sample date:'#13 + s; end else if (ctrl = CbShortDateFormat) then begin FDateFormatSample := fs.ShortDateFormat; s := FormatDateTime(FDateFormatSample, dt, fs); LblDateTimeSample.Caption := 'Sample date:'#13 + s; end else if (ctrl = FCbDateSeparator) then begin s := FormatDateTime(FDateFormatSample, dt, fs); LblDateTimeSample.Caption := 'Sample date:'#13 + s; end else if (ctrl = CbLongTimeFormat) then begin FTimeFormatSample := fs.LongTimeFormat; s := FormatDateTime(FTimeFormatSample, dt, fs); LblDateTimeSample.Caption := 'Sample time:'#13 + s; end else if (ctrl = CbShortTimeFormat) then begin FTimeFormatSample := fs.ShortTimeFormat; s := FormatDateTime(FTimeFormatSample, dt, fs); LblDateTimeSample.Caption := 'Sample time:'#13 + s; end else if (ctrl = FCbTimeSeparator) then begin s := FormatDateTime(FTimeFormatSample, dt, fs); LblDateTimeSample.Caption := 'Sample time:'#13 + s; { end else begin s := AnsiToUTF8(FormatDateTime('c', dt, fs)); LblDateTimeSample.Caption := 'Sample date/time:'#13 + s; } end; LblDateTimeSample.Visible := (PageControl.Activepage = PgDateTime) and ((FDateFormatSample <> '') or (FTimeFormatSample <> '')); // Application.ProcessMessages; end; procedure TFormatSettingsForm.BtnCurrencyClick(Sender: TObject); var F: TCurrencyForm; begin F := TCurrencyForm.Create(nil); try F.CurrencySymbol := EdCurrencySymbol.Text; if F.ShowModal = mrOK then EdCurrencySymbol.Text := F.CurrencySymbol; finally F.Free; end; end; procedure TFormatSettingsForm.EdCurrencySymbolChange(Sender: TObject); var currSym: String; begin currSym := EdCurrencySymbol.Text; BuildCurrencyFormatList(CbPosCurrencyFormat.Items, true, CURR_VALUE, currSym); BuildCurrencyFormatList(CbNegCurrencyFormat.Items, false, CURR_VALUE, currSym); end; procedure TFormatSettingsForm.FormCloseQuery(Sender: TObject; var CanClose: boolean); begin Unused(Sender, CanClose); PageIndex := PageControl.ActivePageIndex; end; procedure TFormatSettingsForm.FormCreate(Sender: TObject); const DROPDOWN_COUNT = 32; var w: Integer; begin PageControl.ActivePageIndex := PageIndex; CbLongDateFormat.DropdownCount := DROPDOWN_COUNT; CbShortDateFormat.DropdownCount := DROPDOWN_COUNT; CbLongTimeFormat.DropdownCount := DROPDOWN_COUNT; CbShortTimeFormat.DropdownCount := DROPDOWN_COUNT; CbPosCurrencyFormat.DropdownCount := DROPDOWN_COUNT; CbNegCurrencyFormat.DropdownCount := DROPDOWN_COUNT; w := CbLongDateFormat.Width; FCbDecimalSeparator := TFormatSeparatorCombo.Create(self); with FCbDecimalSeparator do begin Parent := PgNumber; Left := CbLongDateFormat.Left; Width := w; Top := CbLongDateFormat.Top; TabOrder := 0; SeparatorKind := skDecimal; end; LblDecimalSeparator.FocusControl := FCbDecimalSeparator; FCbThousandSeparator := TFormatSeparatorCombo.Create(self); with FCbThousandSeparator do begin Parent := PgNumber; Left := FCbDecimalSeparator.Left; Width := w; Top := FCBDecimalSeparator.Top + 32; TabOrder := FCbDecimalSeparator.TabOrder + 1; SeparatorKind := skThousand; end; LblThousandSeparator.FocusControl := FCbThousandSeparator; FCbDateSeparator := TFormatSeparatorCombo.Create(self); with FCbDateSeparator do begin Parent := PgDateTime; Left := CbShortDateFormat.Left; Width := w; Top := CbShortDateFormat.Top + 32; TabOrder := CbShortDateFormat.TabOrder + 1; SeparatorKind := skDate; OnChange := @DateTimeFormatChange; OnEnter := @DateTimeFormatChange; end; LblDateSeparator.FocusControl := FCbDateSeparator; FEdLongMonthNames := TMonthDayNamesEdit.Create(self); with FEdLongMonthNames do begin Parent := PgDateTime; Left := CbShortDateFormat.Left; {$IFDEF LCL_FULLVERSION AND LCL_FULLVERSION > 1020600} Width := w; {$ELSE} Width := w - Button.Width; {$ENDIF} Top := CbShortDateFormat.Top + 32*2; OnChange := @DateTimeFormatChange; OnEnter := @DateTimeFormatChange; TabOrder := CbShortDateFormat.TabOrder + 2; end; LblLongMonthNames.FocusControl := FEdLongMonthNames; FEdShortMonthNames := TMonthDayNamesEdit.Create(self); with FEdShortMonthNames do begin Parent := PgDateTime; Left := CbShortDateFormat.Left; Width := FEdLongMonthNames.Width; Top := CbShortDateFormat.Top + 32*3; TabOrder := CbShortDateFormat.TabOrder + 3; OnChange := @DateTimeFormatChange; OnEnter := @DateTimeFormatChange; end; LblShortMonthNames.FocusControl := FEdShortMonthNames; FEdLongDayNames := TMonthDayNamesEdit.Create(self); with FEdLongDayNames do begin Parent := PgDateTime; Left := CbShortDateformat.Left; Width := FEdLongMonthNames.Width; Top := CbShortDateFormat.Top + 32*4; TabOrder := CbShortDateFormat.TabOrder + 4; OnChange := @DateTimeFormatChange; OnEnter := @DateTimeFormatChange; end; LblLongDayNames.FocusControl := FEdLongDayNames; FEdShortDayNames := TMonthDayNamesEdit.Create(self); with FEdShortDayNames do begin Parent := PgDateTime; Left := CbShortDateFormat.Left; Width := FEdLongMonthNames.Width; Top := CbShortDateFormat.Top + 32*5; TabOrder := CbShortDateFormat.TabOrder + 5; OnChange := @DateTimeFormatChange; OnEnter := @DateTimeFormatChange; end; LblShortDayNames.FocusControl := FEdShortDayNames; FCbTimeSeparator := TFormatSeparatorCombo.Create(self); with FCbTimeSeparator do begin Parent := PgDateTime; Left := CbShortTimeFormat.Left; Width := w; Top := CbShortTimeFormat.Top + 32; TabOrder := CbShortTimeFormat.TabOrder + 1; SeparatorKind := skTime; OnChange := @DateTimeFormatChange; OnEnter := @DateTimeFormatChange; end; LblTimeSeparator.FocusControl := FCbTimeSeparator; FDateFormatSample := ''; FTimeFormatSample := ''; FSampleDateTime := now(); LblDateTimeSample.Visible := false; // Published property not available in old Laz versions EdCurrencyDecimals.Alignment := taRightJustify; end; procedure TFormatSettingsForm.OKButtonClick(Sender: TObject); var msg: String; C: TWinControl; cParent: TWinControl; begin if not ValidData(C, msg) then begin cParent := C.Parent; while (cParent <> nil) and not (cParent is TTabSheet) do cParent := cParent.Parent; PageControl.ActivePage := cParent as TTabSheet; if C.CanFocus then C.SetFocus; MessageDlg(msg, mtError, [mbOK], 0); ModalResult := mrNone; end; end; procedure TFormatSettingsForm.PageControlChange(Sender: TObject); begin LblDateTimeSample.Visible := (PageControl.Activepage = PgDateTime) and ((FDateFormatSample <> '') or (FTimeFormatSample <> '')); end; function TFormatSettingsForm.GetFormatSettings: TFormatSettings; begin Result := DefaultFormatSettings; // --- Number format parameters -- // Decimal separator Result.DecimalSeparator := FCbDecimalSeparator.Separator; // Thousand separator Result.ThousandSeparator := FCbThousandSeparator.Separator; if Result.DecimalSeparator = '.' then Result.ListSeparator := ',' else if Result.DecimalSeparator = ',' then Result.ListSeparator := ';'; // --- Currency format parameters --- // Currency symbol Result.CurrencyString := EdCurrencySymbol.Text; // Currency decimal places Result.CurrencyDecimals := EdCurrencyDecimals.Value; // Positive currency format Result.CurrencyFormat := CbPosCurrencyFormat.ItemIndex; // Negative currency format Result.NegCurrFormat := CbNegCurrencyFormat.ItemIndex; // --- Date format parameters --- // Long date format string Result.LongDateFormat := CbLongDateFormat.Text; // Short date format string Result.ShortDateFormat := CbShortDateFormat.Text; // Date separator Result.DateSeparator := FCbDateSeparator.Separator; // Long month names FEdLongMonthNames.GetNames(Result.LongMonthNames); // Short month names FEdShortMonthNames.GetNames(Result.ShortMonthNames); // Long day names FEdLongDayNames.GetNames(Result.LongDayNames); // Short day names FEdShortDayNames.GetNames(Result.ShortDayNames); // --- Time format parameters --- // Long time format string Result.LongTimeFormat := CbLongTimeFormat.Text; // Short time format string Result.ShortTimeFormat := CbShortTimeFormat.Text; // Time separator Result.TimeSeparator := FCbTimeSeparator.Separator; end; procedure TFormatSettingsForm.SetFormatSettings(const AValue: TFormatSettings); var i: Integer; begin // --- Number format parameters --- FCbDecimalSeparator.Separator := AValue.DecimalSeparator; FCbThousandSeparator.Separator := AValue.ThousandSeparator; // --- Currency format parameters --- // Currency symbol EdCurrencySymbol.Text := AValue.CurrencyString; // Currency decimal places EdCurrencyDecimals.Value := AValue.CurrencyDecimals; // Positive currency format CbPosCurrencyFormat.ItemIndex := AValue.CurrencyFormat; // Negative currency format CbNegCurrencyFormat.ItemIndex := AValue.NegCurrFormat; // --- Date format parameters --- // Long date format string i := CbLongDateFormat.Items.IndexOf(AValue.LongDateFormat); if i = -1 then CbLongDateFormat.ItemIndex := CbLongDateFormat.Items.Add(AValue.LongDateFormat) else CbLongDateFormat.ItemIndex := i; // Short date format string i := CbShortDateFormat.Items.IndexOf(AValue.ShortDateFormat); if i = -1 then CbShortDateFormat.ItemIndex := CbShortDateFormat.items.Add(AValue.ShortDateFormat) else CbShortDateFormat.ItemIndex := i; // Date separator FCbDateSeparator.Separator := AValue.DateSeparator; // Long month names FEdLongMonthNames.SetNames(AValue.LongMonthNames, 12, false, 'Error'); // Short month names FEdShortMonthNames.SetNames(AValue.ShortMonthNames, 12, true, 'Error'); // Long day names FEdLongDayNames.SetNames(AValue.LongDayNames, 7, false, 'Error'); // Short month names FEdShortDayNames.SetNames(AValue.ShortDayNames, 7, true, 'Error'); // --- Time format parameters --- // Long time format string i := CbLongTimeFormat.items.IndexOf(AValue.LongTimeFormat); if i = -1 then CbLongTimeFormat.ItemIndex := CbLongTimeFormat.Items.Add(AValue.LongTimeFormat) else CbLongTimeFormat.ItemIndex := i; // Short time format string i := cbShortTimeFormat.Items.IndexOf(AValue.ShortTimeFormat); if i = -1 then CbShortTimeFormat.itemIndex := CbShortTimeFormat.Items.Add(AValue.ShortTimeFormat); // Time separator FCbTimeSeparator.Separator := AValue.TimeSeparator; end; function TFormatSettingsForm.ValidData(out AControl: TWinControl; out AMsg: String): Boolean; begin Result := false; if FCbDecimalSeparator.Separator = FCbThousandSeparator.Separator then begin AControl := FCbDecimalSeparator; AMsg := 'Decimal and thousand separators cannot be the same.'; exit; end; Result := true; end; //initialization // {$I sformatsettingsform.lrs} end.