From 6c0efaf6ebd011d8306425e84b8130bea0c792ef Mon Sep 17 00:00:00 2001 From: wp_xxyyzz Date: Thu, 5 Jun 2014 21:57:23 +0000 Subject: [PATCH] fpspreadsheet: Improvments of TsWorksheetGrid and fpsgrid demo: Fix currency symbol not shown when selecting currency format. Fix showing a zero value when assigning a number format to an empty cell. Fix formula display when selecting an empty cell. Reset number format when selecting "General" format. Move selection to entered cell address in address edit. git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@3144 8e941d3f-bd1b-0410-a28a-d453659cc2b4 --- .../examples/fpsgrid/mainform.lfm | 1 + .../examples/fpsgrid/mainform.pas | 37 ++++++++++++++----- components/fpspreadsheet/fpspreadsheet.pas | 29 +++++++++++++-- .../fpspreadsheet/fpspreadsheetgrid.pas | 12 ++++++ components/fpspreadsheet/fpsutils.pas | 14 ++++++- 5 files changed, 77 insertions(+), 16 deletions(-) diff --git a/components/fpspreadsheet/examples/fpsgrid/mainform.lfm b/components/fpspreadsheet/examples/fpsgrid/mainform.lfm index 635a01c21..32af6122f 100644 --- a/components/fpspreadsheet/examples/fpsgrid/mainform.lfm +++ b/components/fpspreadsheet/examples/fpsgrid/mainform.lfm @@ -411,6 +411,7 @@ object Form1: TForm1 Width = 123 Align = alLeft Alignment = taCenter + OnEditingDone = EdCellAddressEditingDone TabOrder = 1 end object FormulaToolbarSplitter: TSplitter diff --git a/components/fpspreadsheet/examples/fpsgrid/mainform.pas b/components/fpspreadsheet/examples/fpsgrid/mainform.pas index e91259972..8291e05a3 100644 --- a/components/fpspreadsheet/examples/fpsgrid/mainform.pas +++ b/components/fpspreadsheet/examples/fpsgrid/mainform.pas @@ -238,6 +238,7 @@ type procedure CbShowHeadersClick(Sender: TObject); procedure CbShowGridLinesClick(Sender: TObject); procedure CbBackgroundColorGetColors(Sender: TCustomColorBox; Items: TStrings); + procedure EdCellAddressEditingDone(Sender: TObject); procedure EdFrozenColsChange(Sender: TObject); procedure EdFrozenRowsChange(Sender: TObject); procedure FontComboBoxSelect(Sender: TObject); @@ -500,16 +501,21 @@ begin c := GetWorksheetCol(Col); r := GetWorksheetRow(Row); cell := Worksheet.GetCell(r, c); - if IsDateTimeFormat(nf) then begin - if IsDateTimeFormat(cell^.NumberFormat) then - Worksheet.WriteDateTime(cell, cell^.DateTimeValue, nf, fmt) + case cell^.ContentType of + cctNumber, cctDateTime: + if IsDateTimeFormat(nf) then begin + if IsDateTimeFormat(cell^.NumberFormat) then + Worksheet.WriteDateTime(cell, cell^.DateTimeValue, nf, fmt) + else + Worksheet.WriteDateTime(cell, cell^.NumberValue, nf, fmt); + end else begin + if IsDateTimeFormat(cell^.NumberFormat) then + Worksheet.WriteNumber(cell, cell^.DateTimeValue, nf, cell^.Decimals, cell^.CurrencySymbol) + else + Worksheet.WriteNumber(cell, cell^.NumberValue, nf, cell^.Decimals, cell^.CurrencySymbol); + end; else - Worksheet.WriteDateTime(cell, cell^.NumberValue, nf, fmt); - end else begin - if IsDateTimeFormat(cell^.NumberFormat) then - Worksheet.WriteNumber(cell, cell^.DateTimeValue, nf, cell^.Decimals, cell^.CurrencySymbol) - else - Worksheet.WriteNumber(cell, cell^.NumberValue, nf, cell^.Decimals, cell^.CurrencySymbol); + Worksheet.WriteNumberformat(cell, nf, fmt); end; end; @@ -616,6 +622,16 @@ begin end; end; +procedure TForm1.EdCellAddressEditingDone(Sender: TObject); +var + c, r: integer; +begin + if ParseCellString(EdCellAddress.Text, r, c) then begin + WorksheetGrid.Row := WorksheetGrid.GetGridRow(r); + WorksheetGrid.Col := WorksheetGrid.GetGridCol(c); + end; +end; + procedure TForm1.EdFrozenColsChange(Sender: TObject); begin WorksheetGrid.FrozenCols := EdFrozenCols.Value; @@ -755,7 +771,8 @@ begin EdFormula.Text := WorksheetGrid.Worksheet.ReadRPNFormulaAsString(cell) else EdFormula.Text := WorksheetGrid.Worksheet.ReadAsUTF8Text(cell); - end; + end else + EdFormula.Text := ''; EdCellAddress.Text := GetCellString(r, c, [rfRelRow, rfRelCol]); diff --git a/components/fpspreadsheet/fpspreadsheet.pas b/components/fpspreadsheet/fpspreadsheet.pas index 929fa32ac..edf6a3f02 100755 --- a/components/fpspreadsheet/fpspreadsheet.pas +++ b/components/fpspreadsheet/fpspreadsheet.pas @@ -380,7 +380,8 @@ type FOptions: TsSheetOptions; FOnChangeCell: TsCellEvent; FOnChangeFont: TsCellEvent; - procedure RemoveCallback(data, arg: pointer); + function GetFormatSettings: TFormatSettings; + procedure RemoveCallback(data, arg: pointer); protected procedure ChangedCell(ARow, ACol: Cardinal); @@ -468,7 +469,9 @@ type procedure WriteHorAlignment(ARow, ACol: Cardinal; AValue: TsHorAlignment); procedure WriteNumberFormat(ARow, ACol: Cardinal; ANumberFormat: TsNumberFormat; - const AFormatString: String = ''); + const AFormatString: String = ''); overload; + procedure WriteNumberFormat(ACell: PCell; ANumberFormat: TsNumberFormat; + const AFormatString: String = ''); overload; procedure WriteTextRotation(ARow, ACol: Cardinal; ARotation: TsTextRotation); @@ -497,6 +500,7 @@ type { Properties } property Cells: TAVLTree read FCells; property Cols: TIndexedAVLTree read FCols; + property FormatSettings: TFormatSettings read GetFormatSettings; property Rows: TIndexedAVLTree read FRows; property Workbook: TsWorkbook read FWorkbook; @@ -1314,6 +1318,7 @@ begin Result^.Col := ACol; Result^.ContentType := cctEmpty; Result^.BorderStyles := DEFAULT_BORDERSTYLES; + Result^.CurrencySymbol := '?'; Cells.Add(Result); end; @@ -1846,6 +1851,10 @@ begin ACell^.CurrencySymbol := ACurrencySymbol; ACell^.NumberFormatStr := BuildNumberFormatString(ACell^.NumberFormat, Workbook.FormatSettings, ADecimals, ACurrencySymbol); + end else begin + Exclude(ACell^.UsedFormattingFields, uffNumberFormat); + ACell^.NumberFormat := nfGeneral; + ACell^.NumberFormatStr := ''; end; ChangedCell(ACell^.Row, ACell^.Col); @@ -2037,9 +2046,16 @@ procedure TsWorksheet.WriteNumberFormat(ARow, ACol: Cardinal; ANumberFormat: TsNumberFormat; const AFormatString: String = ''); var ACell: PCell; - oldNumFmt: TsNumberFormat; begin ACell := GetCell(ARow, ACol); + WriteNumberFormat(ACell, ANumberFormat, AFormatString); +end; + +procedure TsWorksheet.WriteNumberFormat(ACell: PCell; + ANumberFormat: TsNumberFormat; const AFormatString: String = ''); +begin + if ACell = nil then + exit; Include(ACell^.UsedFormattingFields, uffNumberFormat); ACell^.NumberFormat := ANumberFormat; if (AFormatString = '') then @@ -2047,7 +2063,7 @@ begin Workbook.FormatSettings, ACell^.Decimals, ACell^.CurrencySymbol) else ACell^.NumberFormatStr := AFormatString; - ChangedCell(ARow, ACol); + ChangedCell(ACell^.Row, ACell^.Col); end; procedure TsWorksheet.WriteRPNFormula(ARow, ACol: Cardinal; @@ -2290,6 +2306,11 @@ begin ChangedCell(ARow, ACol); end; +function TsWorksheet.GetFormatSettings: TFormatSettings; +begin + Result := FWorkbook.FormatSettings; +end; + function TsWorksheet.FindRow(ARow: Cardinal): PRow; var LElement: TRow; diff --git a/components/fpspreadsheet/fpspreadsheetgrid.pas b/components/fpspreadsheet/fpspreadsheetgrid.pas index 5f5cc2d79..70de9dc6a 100644 --- a/components/fpspreadsheet/fpspreadsheetgrid.pas +++ b/components/fpspreadsheet/fpspreadsheetgrid.pas @@ -147,6 +147,8 @@ type procedure EditingDone; override; procedure EndUpdate; procedure GetSheets(const ASheets: TStrings); + function GetGridCol(ASheetCol: Cardinal): Integer; + function GetGridRow(ASheetRow: Cardinal): Integer; function GetWorksheetCol(AGridCol: Integer): Cardinal; function GetWorksheetRow(AGridRow: Integer): Cardinal; procedure LoadFromSpreadsheetFile(AFileName: string; @@ -1710,6 +1712,16 @@ begin Result := false; end; +function TsCustomWorksheetGrid.GetGridCol(ASheetCol: Cardinal): Integer; +begin + Result := ASheetCol + FHeaderCount +end; + +function TsCustomWorksheetGrid.GetGridRow(ASheetRow: Cardinal): Integer; +begin + Result := ASheetRow + FHeaderCount; +end; + function TsCustomWorksheetGrid.GetHorAlignment(ACol, ARow: Integer): TsHorAlignment; var cell: PCell; diff --git a/components/fpspreadsheet/fpsutils.pas b/components/fpspreadsheet/fpsutils.pas index 820a2428f..069cde14c 100644 --- a/components/fpspreadsheet/fpsutils.pas +++ b/components/fpspreadsheet/fpsutils.pas @@ -68,6 +68,7 @@ function UTF8TextToXMLText(AText: ansistring): ansistring; function IfThen(ACondition: Boolean; AValue1,AValue2: TsNumberFormat): TsNumberFormat; overload; +function IsCurrencyFormat(AFormat: TsNumberFormat): Boolean; function IsDateTimeFormat(AFormat: TsNumberFormat): Boolean; overload; function IsDateTimeFormat(AFormatStr: String): Boolean; overload; @@ -552,6 +553,13 @@ begin if ACondition then Result := AValue1 else Result := AValue2; end; +{ Checks whether the given number format code is for currency or accounting + i.e. requires currency symbol. } +function IsCurrencyFormat(AFormat: TsNumberFormat): Boolean; +begin + Result := AFormat in [nfCurrency, nfCurrencyRed, nfAccounting, nfAccountingRed]; +end; + { Checks whether the given number format code is for date/times. } function IsDateTimeFormat(AFormat: TsNumberFormat): Boolean; begin @@ -691,7 +699,8 @@ begin cf := AFormatSettings.CurrencyFormat; ncf := AFormatSettings.NegCurrFormat; if ADecimals < 0 then ADecimals := AFormatSettings.CurrencyDecimals; - if ACurrencySymbol = '?' then ACurrencySymbol := AFormatSettings.CurrencyString; + if ACurrencySymbol = '?' then + ACurrencySymbol := AnsiToUTF8(AFormatSettings.CurrencyString); decs := DupeString('0', ADecimals); if ADecimals > 0 then decs := '.' + decs; @@ -735,7 +744,8 @@ begin cf := AFormatSettings.CurrencyFormat; ncf := AFormatSettings.NegCurrFormat; if ADecimals = -1 then ADecimals := AFormatSettings.CurrencyDecimals; - if ACurrencySymbol = '?' then ACurrencySymbol := AFormatSettings.CurrencyString; + if ACurrencySymbol = '?' then + ACurrencySymbol := AnsiToUTF8(AFormatSettings.CurrencyString); decs := DupeString('0', ADecimals); if ADecimals > 0 then decs := '.' + decs; case ANumberFormat of