diff --git a/components/fpspreadsheet/examples/visual/fpsctrls/main.lfm b/components/fpspreadsheet/examples/visual/fpsctrls/main.lfm index 8c63ac616..41c453a66 100644 --- a/components/fpspreadsheet/examples/visual/fpsctrls/main.lfm +++ b/components/fpspreadsheet/examples/visual/fpsctrls/main.lfm @@ -946,6 +946,13 @@ object MainForm: TMainForm Hint = 'Time interval format' NumberFormat = nfTimeInterval end + object AcNumFormatText: TsNumberFormatAction + Category = 'FPSpreadsheet' + WorkbookSource = WorkbookSource + Caption = 'Text' + Hint = 'Text format' + NumberFormat = nfText + end object AcFileOpen: TFileOpen Category = 'File' Caption = '&Open ...' @@ -1018,6 +1025,51 @@ object MainForm: TMainForm Hint = 'Define currency symbols' OnExecute = AcSettingsCurrencyExecute end + object AcSearch: TAction + Category = 'Edit' + Caption = 'Search...' + Hint = 'Search for cells' + ImageIndex = 70 + OnExecute = AcSearchExecute + ShortCut = 16454 + end + object AcShowGridLines: TAction + Category = 'View' + AutoCheck = True + Caption = 'Grid lines' + Checked = True + OnExecute = AcShowGridLinesExecute + OnUpdate = AcShowGridLinesUpdate + end + object AcShowHeaders: TAction + Category = 'View' + AutoCheck = True + Caption = 'Show column/row headers' + Checked = True + OnExecute = AcShowHeadersExecute + OnUpdate = AcShowHeadersUpdate + end + object AcFrozenRows: TAction + Category = 'Worksheet' + AutoCheck = True + Caption = 'Frozen rows' + OnExecute = AcFrozenRowsExecute + OnUpdate = AcFrozenRowsUpdate + end + object AcFrozenCols: TAction + Category = 'Worksheet' + AutoCheck = True + Caption = 'Frozen columns' + OnExecute = AcFrozenColsExecute + OnUpdate = AcFrozenColsUpdate + end + object AcWorksheetRTL: TAction + Category = 'Worksheet' + AutoCheck = True + Caption = 'Text direction inverted' + OnExecute = AcWorksheetRTLExecute + OnUpdate = AcWorksheetRTLUpdate + end object AcIncDecimals: TsDecimalsAction Category = 'FPSpreadsheet' WorkbookSource = WorkbookSource @@ -1448,51 +1500,6 @@ object MainForm: TMainForm Hint = 'All vertical borders' ImageIndex = 43 end - object AcSearch: TAction - Category = 'Edit' - Caption = 'Search...' - Hint = 'Search for cells' - ImageIndex = 70 - OnExecute = AcSearchExecute - ShortCut = 16454 - end - object AcShowGridLines: TAction - Category = 'View' - AutoCheck = True - Caption = 'Grid lines' - Checked = True - OnExecute = AcShowGridLinesExecute - OnUpdate = AcShowGridLinesUpdate - end - object AcShowHeaders: TAction - Category = 'View' - AutoCheck = True - Caption = 'Show column/row headers' - Checked = True - OnExecute = AcShowHeadersExecute - OnUpdate = AcShowHeadersUpdate - end - object AcFrozenRows: TAction - Category = 'Worksheet' - AutoCheck = True - Caption = 'Frozen rows' - OnExecute = AcFrozenRowsExecute - OnUpdate = AcFrozenRowsUpdate - end - object AcFrozenCols: TAction - Category = 'Worksheet' - AutoCheck = True - Caption = 'Frozen columns' - OnExecute = AcFrozenColsExecute - OnUpdate = AcFrozenColsUpdate - end - object AcWorksheetRTL: TAction - Category = 'Worksheet' - AutoCheck = True - Caption = 'Text direction inverted' - OnExecute = AcWorksheetRTLExecute - OnUpdate = AcWorksheetRTLUpdate - end object AcCellBorderDiagUp: TsCellBorderAction Category = 'FPSpreadsheet' WorkbookSource = WorkbookSource @@ -5302,6 +5309,13 @@ object MainForm: TMainForm Action = AcNumFormatTimeInterval AutoCheck = True end + object MenuItem144: TMenuItem + Caption = '-' + end + object MenuItem145: TMenuItem + Action = AcNumFormatText + AutoCheck = True + end end end object MnuView: TMenuItem diff --git a/components/fpspreadsheet/examples/visual/fpsctrls/main.pas b/components/fpspreadsheet/examples/visual/fpsctrls/main.pas index 1ec3f776b..1b246de35 100644 --- a/components/fpspreadsheet/examples/visual/fpsctrls/main.pas +++ b/components/fpspreadsheet/examples/visual/fpsctrls/main.pas @@ -81,6 +81,8 @@ type MenuItem141: TMenuItem; MenuItem142: TMenuItem; MenuItem143: TMenuItem; + MenuItem144: TMenuItem; + MenuItem145: TMenuItem; MnuSettings: TMenuItem; MenuItem11: TMenuItem; MenuItem12: TMenuItem; @@ -273,6 +275,7 @@ type AcNumFormatCustom: TsNumberFormatAction; AcCellBorderDiagUp: TsCellBorderAction; AcCellBorderDiagDown: TsCellBorderAction; + AcNumFormatText: TsNumberFormatAction; Splitter2: TSplitter; Splitter3: TSplitter; ToolBar2: TToolBar; diff --git a/components/fpspreadsheet/examples/visual/shared/snumformatform.lfm b/components/fpspreadsheet/examples/visual/shared/snumformatform.lfm index 1bc07bfab..f9fad4d69 100644 --- a/components/fpspreadsheet/examples/visual/shared/snumformatform.lfm +++ b/components/fpspreadsheet/examples/visual/shared/snumformatform.lfm @@ -8,7 +8,7 @@ object NumFormatForm: TNumFormatForm ClientHeight = 394 ClientWidth = 559 ShowHint = True - LCLVersion = '1.5' + LCLVersion = '1.7' object ButtonPanel1: TButtonPanel Left = 6 Height = 34 @@ -67,6 +67,7 @@ object NumFormatForm: TNumFormatForm 'Currency' 'Date' 'Time' + 'Text' ) ItemHeight = 15 OnClick = LbCategoryClick diff --git a/components/fpspreadsheet/examples/visual/shared/snumformatform.pas b/components/fpspreadsheet/examples/visual/shared/snumformatform.pas index 9d38d8ec5..b9f9ed325 100644 --- a/components/fpspreadsheet/examples/visual/shared/snumformatform.pas +++ b/components/fpspreadsheet/examples/visual/shared/snumformatform.pas @@ -11,7 +11,7 @@ uses type TsNumFormatCategory = (nfcNumber, nfcPercent, nfcScientific, nfcFraction, - nfcCurrency, nfcDate, nfcTime); + nfcCurrency, nfcDate, nfcTime, nfcText); { TNumFormatForm } @@ -56,6 +56,7 @@ type { private declarations } FWorkbook: TsWorkbook; FSampleValue: Double; + FSampleText: String; FGenerator: array[TsNumFormatCategory] of Double; FNumFormatStrOfList: String; FLockCount: Integer; @@ -74,7 +75,8 @@ type public { public declarations } constructor Create(AOwner: TComponent); override; - procedure SetData(ANumFormatStr: String; AWorkbook: TsWorkbook; ASample: Double); + procedure SetData(ANumFormatStr: String; AWorkbook: TsWorkbook; + ASample: variant); property NumFormatStr: String read GetNumFormatStr; end; @@ -89,7 +91,7 @@ implementation {$R *.lfm} uses - LCLType, Math, DateUtils, TypInfo, + LCLType, Math, DateUtils, TypInfo, variants, fpsUtils, fpsNumFormatParser, fpsCurrency, sCurrencyForm; @@ -244,6 +246,8 @@ begin AddToList(nfcTime, '[h]:nn'); AddToList(nfcTime, '[h]:nn:ss'); + AddToList(nfcText, '@'); + // Add user-defined formats if copiedFormats <> nil then begin @@ -351,6 +355,7 @@ begin 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; @@ -419,44 +424,6 @@ begin end; end; end; - (* -{ The global stringlist "NumFormats" contains to format string templates along - with information on the category and of being built-in or user-defined. } -procedure TNumFormatForm.BuildNumFormatLists(AWorkbook: TsWorkbook); -var - cat: TsNumFormatCategory; - nfs: String; - n, i: Integer; - isUserDef: Boolean; - copiedNumFormats: TStringList; -begin - copiedNumFormats := TStringList.Create; - - for cat in TsNumFormatCategory do - begin - FreeAndNil(FNumFormatLists[cat]); - FNumFormatLists[cat] := TsNumFormatList.Create(AWorkbook, true); - end; - - for i:=0 to NumFormats.Count-1 do - begin - nfs := NumFormats.Strings[i]; - n := PtrInt(NumFormats.Objects[i]); - if n >= USER_OFFSET then - begin - isUserDef := true; - // The category numbers of user-defined template items are offset by USER_OFFSET - cat := TsNumFormatCategory(n - USER_OFFSET); - end else - begin - isUserDef := false; - // The category numbers of built-in template items are offset by BUILTIN_OFFSET - cat := TsNumFormatCategory(n - BUILTIN_OFFSET); - end; - FNumFormatLists[cat].AddFormat(nfs); - end; -end; - *) procedure TNumFormatForm.CbCurrSymbolSelect(Sender: TObject); begin @@ -681,42 +648,29 @@ begin begin nfp := CreateNumFormatParams(NumFormats.Strings[i], FWorkbook.FormatSettings); try - genValue := FGenerator[ACategory]; - if nfkTimeInterval in nfp.Sections[0].Kind then - genvalue := genValue + 1.0; - if ACategory = nfcFraction then + if IsTextFormat(nfp) then + s := 'abc' + else 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); + 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; - s := ConvertFloatToStr(genValue, nfp, FWorkbook.FormatSettings); - if s = '' then s := 'General'; LbFormat.Items.AddObject(s, TObject(PtrInt(i))); finally nfp.Free; end; end; end; - { - for i:=0 to FNumFormatLists[ACategory].Count-1 do - begin - nfp := FNumFormatLists[ACategory].Items[i]; - 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 / (IntPower(10, numdigits) - 3); - if digits <> 0 then genvalue := -(1234 + genValue); - end; - s := ConvertFloatToStr(genvalue, nfp, FWorkbook.FormatSettings); - if s = '' then s := 'General'; - Add(s); - end; - } end; CurrSymbolPanel.Visible := (ACategory = nfcCurrency); GbOptions.Visible := not (ACategory in [nfcDate, nfcTime]); @@ -742,7 +696,7 @@ begin end; procedure TNumFormatForm.SetData(ANumFormatStr: String; AWorkbook: TsWorkbook; - ASample: Double); + ASample: variant); var cs: String; begin @@ -752,7 +706,10 @@ begin cs := DefaultFormatSettings.CurrencyString; CbCurrSymbol.ItemIndex := CbCurrSymbol.Items.IndexOf(cs); - FSampleValue := ASample; + if varIsStr(ASample) then + FSampleText := VarToStr(ASample) + else + FSampleValue := ASample; InitNumFormats(FWorkbook.FormatSettings); SetNumFormatStr(ANumFormatStr); end; @@ -852,8 +809,11 @@ begin else Sample.Font.Color := clWindowText; - Sample.Caption := ConvertFloatToStr(FSampleValue, ANumFormatParams, - FWorkbook.FormatSettings); + if IsTextFormat(ANumFormatParams) then + Sample.Caption := ApplyTextFormat(FSampleText, ANumFormatParams) + else + Sample.Caption := ConvertFloatToStr(FSampleValue, ANumFormatParams, + FWorkbook.FormatSettings); BtnAddFormat.Enabled := (EdNumFormatStr.Text <> FNumFormatStrOfList); end; diff --git a/components/fpspreadsheet/fpsactions.pas b/components/fpspreadsheet/fpsactions.pas index 9aeab6fc5..fd13c6078 100644 --- a/components/fpspreadsheet/fpsactions.pas +++ b/components/fpspreadsheet/fpsactions.pas @@ -1247,11 +1247,11 @@ procedure TsCellBorderAction.ApplyFormatToRange(ARange: TsCellRange); if Worksheet.IsMerged(cell) then begin Worksheet.FindMergedRange(cell, r1, c1, r2, c2); - if (r1 >= AStart) and (r2 <= AEnd) then + if (LongInt(r1) >= AStart) and (LongInt(r2) <= AEnd) then begin cell := Worksheet.GetCell(r1, c1); ShowBorder(ABorder, cell, ABorderStyle, AEnable); - while (i <= r2) do begin + while (i <= longint(r2)) do begin cell := GetWorksheet.GetCell(i, AColRow); inc(i); end; @@ -1266,11 +1266,11 @@ procedure TsCellBorderAction.ApplyFormatToRange(ARange: TsCellRange); if Worksheet.IsMerged(cell) then begin Worksheet.FindMergedRange(cell, r1, c1, r2, c2); - if (c1 >= AStart) and (c2 <= AEnd) then + if (longInt(c1) >= AStart) and (LongInt(c2) <= AEnd) then begin cell := Worksheet.GetCell(r1, c1); ShowBorder(ABorder, cell, ABorderStyle, AEnable); - while (i <= c2) do begin + while (i <= longInt(c2)) do begin cell := GetWorksheet.GetCell(AColRow, i); inc(i); end; @@ -1285,9 +1285,6 @@ procedure TsCellBorderAction.ApplyFormatToRange(ARange: TsCellRange); var r, c: LongInt; - r1, c1, r2, c2: Cardinal; - bs: TsCellBorderStyle; - cell: PCell; begin // Top edge of range ShowBorders(cbNorth, ARange.Col1, ARange.Col2, ARange.Row1, false, diff --git a/components/fpspreadsheet/fpscsv.pas b/components/fpspreadsheet/fpscsv.pas index ebcf3fa40..cbbb9a826 100644 --- a/components/fpspreadsheet/fpscsv.pas +++ b/components/fpspreadsheet/fpscsv.pas @@ -318,7 +318,7 @@ var begin Unused(AStream); Unused(ARow, ACol, AValue); - s := FWorksheet.ReadAsUTF8Text(ACell); + s := FWorksheet.ReadAsText(ACell); s := ConvertEncoding(s, EncodingUTF8, FEncoding); FCSVBuilder.AppendCell(s); end; @@ -369,7 +369,7 @@ begin if CSVParams.NumberFormat <> '' then s := Format(CSVParams.NumberFormat, [AValue], FFormatSettings) else - s := FWorksheet.ReadAsUTF8Text(ACell, FFormatSettings); + s := FWorksheet.ReadAsText(ACell, FFormatSettings); s := ConvertEncoding(s, EncodingUTF8, FEncoding); FCSVBuilder.AppendCell(s); end; diff --git a/components/fpspreadsheet/fpshtml.pas b/components/fpspreadsheet/fpshtml.pas index 63147aba5..de9cf31a0 100644 --- a/components/fpspreadsheet/fpshtml.pas +++ b/components/fpspreadsheet/fpshtml.pas @@ -1536,7 +1536,7 @@ var s: String; begin Unused(AValue, ACol, ARow); - s := FWorksheet.ReadAsUTF8Text(ACell); + s := FWorksheet.ReadAsText(ACell); AppendToStream(AStream, '
' + s + '
'); end; @@ -1547,7 +1547,7 @@ var s: String; begin Unused(AValue, ACol, ARow); - s := FWOrksheet.ReadAsUTF8Text(ACell); + s := FWOrksheet.ReadAsText(ACell); AppendToStream(AStream, '
' + s + '
'); end; @@ -1681,7 +1681,7 @@ var s: String; begin Unused(ARow, ACol, AValue); - s := FWorksheet.ReadAsUTF8Text(ACell, FWorkbook.FormatSettings); + s := FWorksheet.ReadAsText(ACell, FWorkbook.FormatSettings); AppendToStream(AStream, '
' + s + '
'); end; diff --git a/components/fpspreadsheet/fpshtmlutils.pas b/components/fpspreadsheet/fpshtmlutils.pas index 22552079e..19027b27e 100644 --- a/components/fpspreadsheet/fpshtmlutils.pas +++ b/components/fpspreadsheet/fpshtmlutils.pas @@ -644,8 +644,6 @@ end; { Stores a font in the workbook's font list. Does not allow duplicates. } function TsHTMLAnalyzer.AddFont(AFont: TsFont): Integer; -const - EPS = 1e-3; var fnt: TsFont; begin diff --git a/components/fpspreadsheet/fpsimages.pas b/components/fpspreadsheet/fpsimages.pas index d96e58418..48bc03fa5 100644 --- a/components/fpspreadsheet/fpsimages.pas +++ b/components/fpspreadsheet/fpsimages.pas @@ -112,7 +112,7 @@ var begin Result := false; - n := AStream.Read(hdr, SizeOf(hdr)); + n := AStream.Read(hdr{%H-}, SizeOf(hdr)); if n < SizeOf(hdr) then exit; if hdr.dSignature <> $464D4520 then exit; @@ -297,7 +297,7 @@ var begin Result := false; - n := AStream.Read(hdr, SizeOf(hdr)); + n := AStream.Read(hdr{%H-}, SizeOf(hdr)); if n < SizeOf(hdr) then exit; if not (hdr.FileID in [$0A, $CD]) then exit; @@ -408,9 +408,6 @@ var function AnalyzeViewbox(AText: String; out w, h: Double): Boolean; var L: TStringList; - val1, val2: Double; - s: String; - code: Integer; begin L := TStringList.Create; try @@ -601,15 +598,13 @@ type Reserved: DWord; // Reserved (always 0) Checksum: Word; // Checksum value for previous 10 words end; -const - TWIPS = 20 * 72; var hdr: TWMFSpecialHeader; n: Int64; begin Result := false; - n := AStream.Read(hdr, SizeOf(hdr)); + n := AStream.Read(hdr{%H-}, SizeOf(hdr)); if n < SizeOf(hdr) then exit; if hdr.Key <> $9AC6CDD7 then exit; diff --git a/components/fpspreadsheet/fpsnumformat.pas b/components/fpspreadsheet/fpsnumformat.pas index cbc29d184..f2813612c 100644 --- a/components/fpspreadsheet/fpsnumformat.pas +++ b/components/fpspreadsheet/fpsnumformat.pas @@ -76,7 +76,8 @@ type nftEscaped, // '\' nftRepeat, nftEmptyCharWidth, - nftTextFormat); + nftTextFormat // '@' + ); {@@ Element of the parsed number format sequence. Each element is identified by a token and has optional parameters stored as integer, float, and/or text. } @@ -96,7 +97,8 @@ type {@@ Summary information classifying a number format section } TsNumFormatKind = (nfkPercent, nfkExp, nfkCurrency, nfkFraction, - nfkDate, nfkTime, nfkTimeInterval, nfkHasColor, nfkHasThSep, nfkHasFactor); + nfkDate, nfkTime, nfkTimeInterval, nfkText, + nfkHasColor, nfkHasThSep, nfkHasFactor); {@@ Set of summary elements classifying and describing a number format section } TsNumFormatKinds = set of TsNumFormatKind; @@ -208,6 +210,7 @@ function BuildNumberFormatString(ANumberFormat: TsNumberFormat; function BuildFormatStringFromSection(const ASection: TsNumFormatSection): String; +function ApplyTextFormat(AText: String; AParams: TsNumFormatParams): String; function ConvertFloatToStr(AValue: Double; AParams: TsNumFormatParams; AFormatSettings: TFormatSettings): String; function CountDecs(AFormatString: String; ADecChars: TsDecsChars = ['0']): Byte; @@ -239,6 +242,8 @@ function IsNumberValue(AText: String; AutoDetectNumberFormat: Boolean; function IsTimeIntervalFormat(ANumFormat: TsNumFormatParams): Boolean; +function IsTextFormat(ANumFormat: TsNumFormatParams): Boolean; + function MakeLongDateFormat(ADateFormat: String): String; function MakeShortDateFormat(ADateFormat: String): String; procedure MakeTimeIntervalMask(Src: String; var Dest: String); @@ -1259,6 +1264,8 @@ begin decs := DupeString('0', ADecimals); if ADecimals > 0 then decs := '.' + decs; case ANumberFormat of + nfText: + Result := '@'; nfFixed: Result := '0' + decs; nfFixedTh: @@ -1373,9 +1380,6 @@ begin nftEscaped: if element.TextValue <> '' then Result := Result + '\' + element.TextValue; - nftTextFormat: - if element.TextValue <> '' then - Result := Result + element.TextValue; nftRepeat: if element.TextValue <> '' then Result := Result + '*' + element.TextValue; nftColor: @@ -1390,6 +1394,8 @@ begin scCyan : Result := '[cyan]'; else Result := Format('[Color%d]', [element.IntValue]); end; + nftTextFormat: + Result := '@'; end; end; end; @@ -1422,6 +1428,29 @@ begin end; end; +{@@ ---------------------------------------------------------------------------- + Applies a text format to a text. The text placeholder is @. Supports + appending and prepending text. +-------------------------------------------------------------------------------} +function ApplyTextFormat(AText: String; AParams: TsNumFormatParams): String; +var + sct: TsNumFormatSection; + element: TsNumFormatElement; + i, n: Integer; +begin + Result := ''; + for sct in AParams.Sections do + for i := 0 to High(sct.Elements) do begin + element := sct.Elements[i]; + case element.Token of + nftTextFormat: + Result := Result + AText; + nftText: + Result := Result + element.TextValue; + end; + end; +end; + {@@ ---------------------------------------------------------------------------- Checks whether the specified text corresponds to a boolean value. For this, it must match the specified TRUE and FALSE text phrases. @@ -1742,6 +1771,12 @@ begin (ANumFormat.Sections[0].Kind * [nfkTimeInterval] <> []); end; +function IsTextFormat(ANumFormat: TsNumFormatParams): Boolean; +begin + Result := (ANumFormat <> nil) and + (ANumFormat.Sections[0].Kind = [nfkText]); +end; + {@@ ---------------------------------------------------------------------------- Creates a long date format string out of a short date format string. Retains the order of year-month-day and the separators, but uses 4 digits diff --git a/components/fpspreadsheet/fpsnumformatparser.pas b/components/fpspreadsheet/fpsnumformatparser.pas index e61f0dc96..9435f334c 100644 --- a/components/fpspreadsheet/fpsnumformatparser.pas +++ b/components/fpspreadsheet/fpsnumformatparser.pas @@ -25,6 +25,7 @@ const psErrMultipleExpChars = 11; psErrGeneralExpected = 12; psAmbiguousSymbol = 13; + psErrNoValidTextFormat = 14; type @@ -313,11 +314,11 @@ begin exit; end; - i := 0; isMonthMinute := false; for el := 0 to High(section^.Elements) do + begin case section^.Elements[el].Token of nftZeroDecs: section^.Decimals := section^.Elements[el].IntValue; @@ -377,7 +378,10 @@ begin end; nftIntTh: section^.Kind := section^.Kind + [nfkHasThSep]; + nftTextFormat: + section^.Kind := section^.Kind + [nfkText]; end; + end; // for if FStatus <> psOK then exit; @@ -389,6 +393,11 @@ begin exit; end; + if (Length(FSections) = 1) and (section^.Kind = [nfkText]) then begin + section^.NumFormat := nfText; + exit; + end; + section^.NumFormat := nfCustom; if (section^.Kind * [nfkDate, nfkTime] <> []) or isMonthMinute then @@ -450,78 +459,6 @@ begin if section^.Color = scRed then section^.NumFormat := nfCurrencyRed; end; - - { - el := 0; - while el < Length(section^.Elements) do - begin - if IsNumberAt(ASection, el, nf, decs, next) then begin - section^.Decimals := decs; - if nf = nfFixedTh then begin - if (nfkCurrency in section^.Kind) then - section^.NumFormat := nfCurrency - else - section^.NumFormat := nfFixedTh - end else - begin - section^.NumFormat := nf; - if (nfkPercent in section^.Kind) then - section^.NumFormat := nfPercentage - else - if (nfkExp in section^.Kind) then - section^.NumFormat := nfExp - else - if (nfkCurrency in section^.Kind) then - section^.NumFormat := nfCurrency - else - if (nfkFraction in section^.Kind) and (decs = 0) then begin - f1 := section^.Elements[el].IntValue; // int part or numerator - el := next; - while IsTokenAt(nftSpace, ASection, el) or IsTextAt(' ', ASection, el) do - inc(el); - if IsTokenAt(nftFracSymbol, ASection, el) then begin - inc(el); - while IsTokenAt(nftSpace, ASection, el) or IsTextAt(' ', aSection, el) do - inc(el); - if IsNumberAt(ASection, el, nf, decs, next) and (nf in [nfFixed, nfFraction]) and (decs = 0) then - begin - section^.FracInt := 0; - section^.FracNumerator := f1; - section^.FracDenominator := section^.Elements[el].IntValue; - section^.NumFormat := nfFraction; - end; - end else - if IsNumberAt(ASection, el, nf, decs, next) and (nf in [nfFixed, nfFraction]) and (decs = 0) then - begin - f2 := section^.Elements[el].IntValue; - el := next; - while IsTokenAt(nftSpace, ASection, el) or IsTextAt(' ', ASection, el) do - inc(el); - if IsTokenAt(nftFracSymbol, ASection, el) then - begin - inc(el); - while IsTokenAt(nftSpace, ASection, el) or IsTextAt(' ', ASection, el) do - inc(el); - if IsNumberAt(ASection, el, nf, decs, next) and (nf in [nfFixed, nfFraction]) and (decs=0) then - begin - section^.FracInt := f1; - section^.FracNumerator := f2; - section^.FracDenominator := section^.Elements[el].IntValue; - section^.NumFormat := nfFraction; - end; - end; - end; - end; - end; - break; - end else - if IsTokenAt(nftColor, ASection, el) then - section^.Color := section^.Elements[el].IntValue; - inc(el); - end; - if (section^.NumFormat = nfCurrency) and (section^.Color = scRed) then - section^.NumFormat := nfCurrencyRed; - } end; end; diff --git a/components/fpspreadsheet/fpsopendocument.pas b/components/fpspreadsheet/fpsopendocument.pas index 7cd788d28..f6ddbaf51 100755 --- a/components/fpspreadsheet/fpsopendocument.pas +++ b/components/fpspreadsheet/fpsopendocument.pas @@ -284,18 +284,18 @@ const SCHEMAS_XMLNS_TABLE = 'urn:oasis:names:tc:opendocument:xmlns:table:1.0'; SCHEMAS_XMLNS_TEXT = 'urn:oasis:names:tc:opendocument:xmlns:text:1.0'; SCHEMAS_XMLNS_V = 'urn:schemas-microsoft-com:vml'; - SCHEMAS_XMLNS_NUMBER = 'urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0'; - SCHEMAS_XMLNS_CHART = 'urn:oasis:names:tc:opendocument:xmlns:chart:1.0'; - SCHEMAS_XMLNS_DR3D = 'urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0'; - SCHEMAS_XMLNS_MATH = 'http://www.w3.org/1998/Math/MathML'; - SCHEMAS_XMLNS_FORM = 'urn:oasis:names:tc:opendocument:xmlns:form:1.0'; - SCHEMAS_XMLNS_SCRIPT = 'urn:oasis:names:tc:opendocument:xmlns:script:1.0'; - SCHEMAS_XMLNS_OOOW = 'http://openoffice.org/2004/writer'; - SCHEMAS_XMLNS_OOOC = 'http://openoffice.org/2004/calc'; - SCHEMAS_XMLNS_DOM = 'http://www.w3.org/2001/xml-events'; - SCHEMAS_XMLNS_XFORMS = 'http://www.w3.org/2002/xforms'; - SCHEMAS_XMLNS_XSD = 'http://www.w3.org/2001/XMLSchema'; - SCHEMAS_XMLNS_XSI = 'http://www.w3.org/2001/XMLSchema-instance'; + {%H-}SCHEMAS_XMLNS_NUMBER = 'urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0'; + {%H-}SCHEMAS_XMLNS_CHART = 'urn:oasis:names:tc:opendocument:xmlns:chart:1.0'; + {%H-}SCHEMAS_XMLNS_DR3D = 'urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0'; + {%H-}SCHEMAS_XMLNS_MATH = 'http://www.w3.org/1998/Math/MathML'; + {%H-}SCHEMAS_XMLNS_FORM = 'urn:oasis:names:tc:opendocument:xmlns:form:1.0'; + {%H-}SCHEMAS_XMLNS_SCRIPT = 'urn:oasis:names:tc:opendocument:xmlns:script:1.0'; + {%H-}SCHEMAS_XMLNS_OOOW = 'http://openoffice.org/2004/writer'; + {%H-}SCHEMAS_XMLNS_OOOC = 'http://openoffice.org/2004/calc'; + {%H-}SCHEMAS_XMLNS_DOM = 'http://www.w3.org/2001/xml-events'; + {%H-}SCHEMAS_XMLNS_XFORMS = 'http://www.w3.org/2002/xforms'; + {%H-}SCHEMAS_XMLNS_XSD = 'http://www.w3.org/2001/XMLSchema'; + {%H-}SCHEMAS_XMLNS_XSI = 'http://www.w3.org/2001/XMLSchema-instance'; { DATEMODE similar to but not the same as XLS format; used in time only values. } DATEMODE_1899_BASE=0; //apparently 1899-12-30 for ODF in FPC DateTime; @@ -4562,15 +4562,15 @@ var styleName: String; colsRepeated: Integer; colsRepeatedStr: String; - firstRepeatedPrintCol, lastRepeatedPrintCol: Cardinal; + firstRepeatedPrintCol, lastRepeatedPrintCol: Longint; headerCols: Boolean; begin widthMultiplier := Workbook.GetFont(0).Size / 2; lastCol := ASheet.GetLastColIndex; firstRepeatedPrintCol := ASheet.PageLayout.RepeatedCols.FirstIndex; lastRepeatedPrintCol := ASheet.PageLayout.RepeatedCols.LastIndex; - if (firstRepeatedPrintCol <> UNASSIGNED_ROW_COL_INDEX) and - (lastRepeatedPrintCol = UNASSIGNED_ROW_COL_INDEX) + if (firstRepeatedPrintCol <> Longint(UNASSIGNED_ROW_COL_INDEX)) and + (lastRepeatedPrintCol = LongInt(UNASSIGNED_ROW_COL_INDEX)) then lastRepeatedPrintCol := firstRepeatedPrintCol; @@ -5747,12 +5747,10 @@ function TsSpreadOpenDocWriter.WritePrintRangesAsXMLString(ASheet: TsWorksheet): var i: Integer; rng: TsCellRange; - srng: String; sheetName: String; begin if ASheet.PageLayout.NumPrintRanges > 0 then begin - srng := ''; for i := 0 to ASheet.PageLayout.NumPrintRanges - 1 do begin rng := ASheet.PageLayout.PrintRange[i]; @@ -6457,7 +6455,7 @@ begin DisplayStr := '1.#INF'; end else begin StrValue := FloatToStr(AValue, FPointSeparatorSettings); // Uses '.' as decimal separator - DisplayStr := FWorksheet.ReadAsUTF8Text(ACell); //FloatToStr(AValue); // Uses locale decimal separator + DisplayStr := FWorksheet.ReadAsText(ACell); //FloatToStr(AValue); // Uses locale decimal separator end; // Hyperlink @@ -6530,7 +6528,7 @@ begin DecodeTime(AValue, h,m,s,ms); strValue := Format('PT%.2dH%.2dM%.2d.%.3dS', [trunc(AValue)*24+h, m, s, ms], FPointSeparatorSettings); // strValue := FormatDateTime(ISO8601FormatHoursOverflow, AValue, [fdoInterval]); - displayStr := FWorksheet.ReadAsUTF8Text(ACell); + displayStr := FWorksheet.ReadAsText(ACell); // displayStr := FormatDateTime(fmt.NumberFormatStr, AValue, [fdoInterval]); AppendToStream(AStream, Format( '' + @@ -6548,7 +6546,7 @@ begin else isTimeOnly := false; strValue := FormatDateTime(DATE_FMT[isTimeOnly], AValue); - displayStr := FWorksheet.ReadAsUTF8Text(ACell); + displayStr := FWorksheet.ReadAsText(ACell); AppendToStream(AStream, Format( '' + comment + diff --git a/components/fpspreadsheet/fpspreadsheet.pas b/components/fpspreadsheet/fpspreadsheet.pas index 97f402228..131589b8c 100755 --- a/components/fpspreadsheet/fpspreadsheet.pas +++ b/components/fpspreadsheet/fpspreadsheet.pas @@ -1122,7 +1122,7 @@ begin rtInteger : WriteNumber(ACell, res.ResInteger); rtFloat : WriteNumber(ACell, res.ResFloat); rtDateTime : WriteDateTime(ACell, res.ResDateTime); - rtString : WriteUTF8Text(ACell, res.ResString); + rtString : WriteText(ACell, res.ResString); rtHyperlink : begin link := ArgToString(res); p := pos(HYPERLINK_SEPARATOR, link); @@ -1133,7 +1133,7 @@ begin end else txt := link; WriteHyperlink(ACell, link); - WriteUTF8Text(ACell, txt); + WriteText(ACell, txt); end; rtBoolean : WriteBoolValue(ACell, res.ResBoolean); rtCell : begin @@ -1141,7 +1141,7 @@ begin case cell^.ContentType of cctNumber : WriteNumber(ACell, cell^.NumberValue); cctDateTime : WriteDateTime(ACell, cell^.DateTimeValue); - cctUTF8String: WriteUTF8Text(ACell, cell^.UTF8StringValue); + cctUTF8String: WriteText(ACell, cell^.UTF8StringValue); cctBool : WriteBoolValue(ACell, cell^.Boolvalue); cctError : WriteErrorValue(ACell, cell^.ErrorValue); cctEmpty : WriteBlank(ACell); @@ -2939,17 +2939,12 @@ end; function TsWorksheet.ReadCellBorderStyles(ACell: PCell): TsCellBorderStyles; var fmt: PsCellFormat; - b: TsCellBorder; begin Result := DEFAULT_BORDERSTYLES; if ACell <> nil then begin fmt := Workbook.GetPointerToCellFormat(ACell^.FormatIndex); Result := Fmt^.BorderStyles; - { - for b in fmt^.Border do - Result[b] := fmt^.BorderStyles[b]; - } end; end; @@ -3446,7 +3441,7 @@ begin img^.Index := Workbook.AddEmbeddedStream(AFileName); Workbook.GetEmbeddedStream(img^.Index).LoadFromFile(AFileName); end; - FImages.Add(img); + Result := FImages.Add(img); end; {@@ ---------------------------------------------------------------------------- @@ -4283,7 +4278,7 @@ begin if ACell <> nil then begin ACell^.FormulaValue := ''; if HasHyperlink(ACell) then - WriteUTF8Text(ACell, '') // '' will be replaced by the hyperlink target. + WriteText(ACell, '') // '' will be replaced by the hyperlink target. else begin ACell^.ContentType := cctEmpty; @@ -4365,23 +4360,42 @@ begin if ACell = nil then exit; - fmt := Workbook.GetCellFormat(ACell^.FormatIndex); - numFmtParams := Workbook.GetNumberFormat(fmt.NumberFormatIndex); + ACell^.FormulaValue := ''; if AValue = '' then begin - WriteUTF8Text(ACell, ''); + WriteText(ACell, ''); exit; end; + // Force text format by putting an apostrophe at the text beginning + if AValue[1] = '''' then + begin + Delete(AValue, 1, 1); + WriteNumberFormat(ACell, nfText); + end; + + fmt := Workbook.GetCellFormat(ACell^.FormatIndex); + numFmtParams := Workbook.GetNumberFormat(fmt.NumberFormatIndex); + isPercent := Pos('%', AValue) = Length(AValue); if isPercent then Delete(AValue, Length(AValue), 1); - ACell^.FormulaValue := ''; + { + if IsTextFormat(numFmtParams) then + begin + WriteText(ACell, AValue); + exit; + end; + } if TryStrToCurrency(AValue, number, currSym, FWorkbook.FormatSettings) then begin WriteCurrency(ACell, number, nfCurrencyRed, -1, currSym); + if IsTextFormat(numFmtParams) then begin + WriteNumberFormat(ACell, nfText); + WriteText(ACell, AValue); + end; exit; end; @@ -4389,6 +4403,11 @@ begin begin WriteNumber(ACell, number); WriteFractionFormat(ACell, ismixed, maxdig, maxdig); + if IsTextFormat(numFmtParams) then + begin + WriteNumberFormat(ACell, nfText); + WriteText(ACell, AValue); + end; exit; end; @@ -4403,6 +4422,11 @@ begin else WriteNumber(ACell, number); end; + if IsTextFormat(numFmtParams) then + begin + WriteNumberFormat(ACell, nfText); + WriteText(ACell, AValue); + end; exit; end; @@ -4420,18 +4444,23 @@ begin end else if frac(number) = 0.0 then // this is a date alone begin - if not IsDateFormat(numFmtParams) then + // if not IsDateFormat(numFmtParams) then WriteDateTime(ACell, number, nfShortDate); end else if not IsDateTimeFormat(fmt.NumberFormat) then WriteDateTime(ACell, number, nfShortDateTime) else WriteDateTime(ACell, number); + if IsTextFormat(numFmtParams) then + begin + WriteNumberFormat(ACell, nfText); + WriteText(ACell, AValue); + end; exit; end; HTMLToRichText(FWorkbook, ReadcellFont(ACell), AValue, plain, rtParams); - WriteUTF8Text(ACell, plain, rtParams); + WriteText(ACell, plain, rtParams); end; {@@ ---------------------------------------------------------------------------- @@ -4754,6 +4783,9 @@ procedure TsWorksheet.WriteDateTimeFormat(ACell: PCell; var fmt: TsCellFormat; nfs: String; + nfp: TsNumFormatParams; + isTextFmt, wasTextFmt: Boolean; + oldVal: String; begin if ACell = nil then exit; @@ -4761,15 +4793,22 @@ begin if not ((ANumFormat in [nfGeneral, nfCustom]) or IsDateTimeFormat(ANumFormat)) then raise Exception.Create('WriteDateTimeFormat can only be called with date/time formats.'); + isTextFmt := false; + wasTextFmt := false; + fmt := FWorkbook.GetCellFormat(ACell^.FormatIndex); fmt.NumberFormat := ANumFormat; if (ANumFormat <> nfGeneral) then begin + nfp := Workbook.GetNumberFormat(fmt.NumberFormatIndex); + wasTextFmt := IsTextFormat(nfp); + oldval := ReadAsText(ACell); Include(fmt.UsedFormattingFields, uffNumberFormat); if (ANumFormatString = '') then nfs := BuildDateTimeFormatString(ANumFormat, Workbook.FormatSettings) else nfs := ANumFormatString; + isTextFmt := (nfs = '@'); end else begin Exclude(fmt.UsedFormattingFields, uffNumberFormat); @@ -4780,6 +4819,12 @@ begin fmt.NumberFormatIndex := Workbook.AddNumberFormat(nfs); ACell^.FormatIndex := FWorkbook.AddCellFormat(fmt); + if isTextFmt then + WriteText(ACell, oldval) + else + if wasTextFmt then + WriteCellValueAsString(ACell, ACell^.UTF8StringValue); + ChangedCell(ACell^.Row, ACell^.Col); end; @@ -4968,13 +5013,19 @@ procedure TsWorksheet.WriteNumberFormat(ACell: PCell; var fmt: TsCellFormat; fmtStr: String; + nfp: TsNumFormatParams; + wasTextFmt: Boolean; begin if ACell = nil then exit; + wasTextFmt := false; + fmt := Workbook.GetCellFormat(ACell^.FormatIndex); fmt.NumberFormat := ANumFormat; if ANumFormat <> nfGeneral then begin + nfp := Workbook.GetNumberFormat(fmt.NumberFormatIndex); + wasTextFmt := IsTextFormat(nfp); Include(fmt.UsedFormattingFields, uffNumberFormat); if IsCurrencyFormat(ANumFormat) then begin @@ -4991,6 +5042,9 @@ begin end; ACell^.FormatIndex := Workbook.AddCellFormat(fmt); + if wasTextFmt then + WriteCellValueAsString(ACell, ACell^.UTF8StringValue); + ChangedCell(ACell^.Row, ACell^.Col); end; @@ -5077,17 +5131,28 @@ procedure TsWorksheet.WriteNumberFormat(ACell: PCell; var fmt: TsCellFormat; fmtStr: String; + nfp: TsNumFormatParams; + oldval: String; + isTextFmt, wasTextFmt: Boolean; begin if ACell = nil then exit; + isTextFmt := false; + wasTextFmt := false; + fmt := Workbook.GetCellFormat(ACell^.FormatIndex); + if ANumFormat <> nfGeneral then begin + nfp := Workbook.GetNumberFormat(fmt.NumberFormatIndex); + wasTextFmt := IsTextFormat(nfp); + oldval := ReadAsText(ACell); Include(fmt.UsedFormattingFields, uffNumberFormat); if (ANumFormatString = '') then fmtStr := BuildNumberFormatString(ANumFormat, Workbook.FormatSettings) else fmtStr := ANumFormatString; + isTextFmt := (fmtstr = '@'); fmt.NumberFormatIndex := Workbook.AddNumberFormat(fmtStr); end else begin Exclude(fmt.UsedFormattingFields, uffNumberFormat); @@ -5095,6 +5160,12 @@ begin end; ACell^.FormatIndex := Workbook.AddCellFormat(fmt); + if isTextFmt then + WriteText(ACell, oldval) + else + if wasTextFmt then + WriteCellValueAsString(ACell, ACell^.UTF8StringValue); + ChangedCell(ACell^.Row, ACell^.Col); end; @@ -8131,10 +8202,11 @@ var r, c: LongInt; dr, dc: LongInt; srcCell, destCell: PCell; - i: Integer; // counter - ncs, nrs, ncd, nrd: Integer; // Num cols source, num rows source, ... - rdest, cdest: Integer; // row and column index at destination - nselS, nselD: Integer; // count of selected blocks + i: Integer; // counter + ncs, nrs: Integer; // Num cols source, num rows source, ... + ncd, nrd: Integer; + rdest, cdest: Integer; // row and column index at destination + nselS, nselD: Integer; // count of selected blocks begin if AStream = nil then exit; @@ -8224,25 +8296,25 @@ begin // Iterate over all destination blocks for i := 0 to nselD-1 do begin - // size of current selected block at destination + // size of currently selected block at destination with ActiveWorksheet.GetSelection[i] do begin - ncd := LongInt(Col2) - LongInt(Col1) + 1; - nrd := LongInt(Row2) - LongInt(Row1) + 1; + ncd := Integer(Col2) - Integer(Col1) + 1; + nrd := Integer(Row2) - Integer(Row1) + 1; end; r := ActiveWorksheet.GetSelection[i].Row1; - while r <= ActiveWorksheet.GetSelection[i].Row2 do begin + while r <= longint(ActiveWorksheet.GetSelection[i].Row2) do begin c := ActiveWorksheet.GetSelection[i].Col1; - while c <= ActiveWorksheet.GetSelection[i].Col2 do begin + while c <= longint(ActiveWorksheet.GetSelection[i].Col2) do begin dr := r - clipsheet.GetFirstRowIndex; dc := c - clipsheet.GetFirstColIndex; for srccell in clipsheet.Cells do begin - rdest := srccell^.Row + dr; - if rdest > ActiveWorksheet.GetSelection[i].Row2 then + rdest := longint(srccell^.Row) + dr; + if rdest > integer(ActiveWorksheet.GetSelection[i].Row2) then Continue; - cdest := srcCell^.Col + dc; - if cdest > ActiveWorksheet.GetSelection[i].Col2 then + cdest := longint(srcCell^.Col) + dc; + if cdest > integer(ActiveWorksheet.GetSelection[i].Col2) then Continue; destcell := ActiveWorksheet.GetCell( LongInt(srcCell^.Row) + dr, diff --git a/components/fpspreadsheet/fpspreadsheetgrid.pas b/components/fpspreadsheet/fpspreadsheetgrid.pas index e2f5332e8..b6a657bdb 100644 --- a/components/fpspreadsheet/fpspreadsheetgrid.pas +++ b/components/fpspreadsheet/fpspreadsheetgrid.pas @@ -44,7 +44,7 @@ type TsSelPen = class(TPen) public - constructor Create; + constructor Create; override; published property Width stored true default 3; property JoinStyle default pjsMiter; @@ -1544,7 +1544,6 @@ var r1, c1, r2, c2: Cardinal; cell: PCell; Rct: TRect; - s: String; delta: Integer; begin inherited; @@ -1553,7 +1552,6 @@ begin delta := FSelPen.Width div 2; cell := Worksheet.FindCell(GetWorksheetRow(Row), GetWorksheetCol(Col)); if Worksheet.IsMerged(cell) then begin - s := Editor.ClassName; Worksheet.FindMergedRange(cell, r1,c1,r2,c2); Rct := CellRect(GetGridCol(c1), GetGridRow(r1), GetGridCol(c2), GetGridRow(r2)); end else @@ -1833,63 +1831,17 @@ const 2, 1, 2, 1, 2, 2); var - width3: Boolean; // line is 3 pixels wide deltax, deltay: Integer; angle: Double; savedCosmetic: Boolean; begin savedCosmetic := Canvas.Pen.Cosmetic; - width3 := (ABorderStyle.LineStyle in [lsThick, lsDouble]); - Canvas.Pen.Style := PEN_STYLES[ABorderStyle.LineStyle]; Canvas.Pen.Width := PEN_WIDTHS[ABorderStyle.LineStyle]; Canvas.Pen.Color := ABorderStyle.Color and $00FFFFFF; Canvas.Pen.EndCap := pecSquare; if ABorderStyle.LineStyle = lsHair then Canvas.Pen.Cosmetic := false; - (* - // Workaround until efficient drawing procedures for diagonal "hair" lines - // is available - { - if (ADrawDirection in [drawDiagUp, drawDiagDown]) and - (ABorderStyle.LineStyle = lsHair) - then - ABorderStyle.LineStyle := lsDotted; - } - - // Tuning the rectangle to avoid issues at the grid borders and to get nice corners - if (ABorderStyle.LineStyle in [lsMedium, lsMediumDash, lsMediumDashDot, - lsMediumDashDotDot, lsSlantDashDot, lsThick, lsDouble]) then - begin - { - if ACol = ColCount-1 then - begin - if (ADrawDirection = drawVert) and (ACoord = ARect.Right-1) and width3 - then dec(ACoord); - dec(ARect.Right); - end; - if ARow = RowCount-1 then - begin - if (ADrawDirection = drawHor) and (ACoord = ARect.Bottom-1) and width3 - then dec(ACoord); - dec(ARect.Bottom); - end; - } - end; - if ABorderStyle.LineStyle in [lsMedium, lsMediumDash, lsMediumDashDot, - lsMediumDashDotDot, lsSlantDashDot, lsThick, lsHair] then - begin - if (ADrawDirection = drawHor) then - dec(ARect.Right, 1) - else if (ADrawDirection = drawVert) then - dec(ARect.Bottom, 1) - else if (ADrawDirection in [drawDiagUp, drawDiagDown]) then - begin - dec(ARect.Right, 1); - dec(ARect.Bottom, 2); - end; - end; - *) // Painting case ABorderStyle.LineStyle of lsThin, lsMedium, lsThick, lsDotted, lsDashed, lsDashDot, lsDashDotDot, @@ -2914,7 +2866,6 @@ function TsCustomWorksheetGrid.GetCellBorderStyle(ACol, ARow: Integer; ABorder: TsCellBorder): TsCellBorderStyle; var cell: PCell; - base: PCell; begin Result := DEFAULT_BORDERSTYLES[ABorder]; if Assigned(Worksheet) then @@ -3320,10 +3271,10 @@ begin r := GetWorksheetRow(ARow); c := GetWorksheetCol(ACol); - if (r + ADeltaRow < 0) or (c + ADeltaCol < 0) then + if (longint(r) + ADeltaRow < 0) or (longint(c) + ADeltaCol < 0) then neighborcell := nil else - neighborcell := Worksheet.FindCell(r + ADeltaRow, c + ADeltaCol); + neighborcell := Worksheet.FindCell(longint(r) + ADeltaRow, longint(c) + ADeltaCol); // Only cell has border, but neighbor has not if HasBorder(ACell, border) and not HasBorder(neighborCell, neighborBorder) then @@ -3474,7 +3425,7 @@ procedure TsCustomWorksheetGrid.HeaderSizing(const IsColumn:boolean; const AIndex,ASize:Integer); var gc, gr: Integer; - sc, sr, sr1, sr2, sc1, sc2, si: Cardinal; + sr1, sr2, sc1, sc2, si: Cardinal; cell: PCell; begin inherited; @@ -3486,10 +3437,8 @@ begin si := IfThen(IsColumn, GetWorksheetCol(AIndex), GetWorksheetRow(AIndex)); for gc := GetFirstVisibleColumn to GetLastVisibleColumn do begin - sc := GetWorksheetCol(gc); for gr := GetFirstVisibleRow to GetLastVisibleRow do begin - sr := GetWorksheetRow(gr); cell := Worksheet.FindCell(gr, gc); if Worksheet.IsMerged(cell) then begin Worksheet.FindMergedRange(cell, sr1, sc1, sr2, sc2); diff --git a/components/fpspreadsheet/fpstypes.pas b/components/fpspreadsheet/fpstypes.pas index b5ba850eb..7e1fabee1 100644 --- a/components/fpspreadsheet/fpstypes.pas +++ b/components/fpspreadsheet/fpstypes.pas @@ -546,6 +546,8 @@ type // dates and times nfShortDateTime, nfShortDate, nfLongDate, nfShortTime, nfLongTime, nfShortTimeAM, nfLongTimeAM, nfDayMonth, nfMonthYear, nfTimeInterval, + // text + nfText, // other (format string goes directly into the file) nfCustom); diff --git a/components/fpspreadsheet/fpsutils.pas b/components/fpspreadsheet/fpsutils.pas index 7aa0144d0..095bb3910 100644 --- a/components/fpspreadsheet/fpsutils.pas +++ b/components/fpspreadsheet/fpsutils.pas @@ -2187,8 +2187,6 @@ end; @param AFont2 Pointer to the second font to be compared -------------------------------------------------------------------------------} function SameFont(AFont1, AFont2: TsFont): Boolean; -const - EPS = 1E-3; begin if (AFont1 = nil) and (AFont2 = nil) then Result := true diff --git a/components/fpspreadsheet/fpsvisualutils.pas b/components/fpspreadsheet/fpsvisualutils.pas index dbf7c5516..ac26d74e1 100644 --- a/components/fpspreadsheet/fpsvisualutils.pas +++ b/components/fpspreadsheet/fpsvisualutils.pas @@ -356,7 +356,7 @@ end; { Draw lines in horizontal orienation } procedure TsTextPainter.DrawHor(AOverrideTextColor: TColor); var - xpos, ypos, dx, j: Integer; + xpos, ypos, j: Integer; lineinfo: TsLineInfo; pEnd: PChar; begin @@ -447,7 +447,7 @@ var xpos, ypos, dx: Integer; j: Integer; lineinfo: TsLineInfo; - pEnd, p: PChar; + pEnd: PChar; begin // (1) Get starting point of line lineinfo := TsLineInfo(FLines[0]); diff --git a/components/fpspreadsheet/wikitable.pas b/components/fpspreadsheet/wikitable.pas index 05e5226f9..39efef76f 100644 --- a/components/fpspreadsheet/wikitable.pas +++ b/components/fpspreadsheet/wikitable.pas @@ -331,7 +331,7 @@ begin for j := 0 to lLineSplitter.Tokens.Count-1 do begin lCurToken := lLineSplitter.Tokens[j]; - FWorksheet.WriteUTF8Text(i, j, lCurToken.Value); + FWorksheet.WriteText(i, j, lCurToken.Value); if lCurToken.Bold then FWorksheet.WriteFontStyle(i, j, [fssBold]); if lCurToken.UseBackgroundColor then @@ -463,7 +463,7 @@ begin for j := 0 to FWorksheet.GetLastColIndex do begin lCell := FWorksheet.FindCell(i, j); - lCurStr := FWorksheet.ReadAsUTF8Text(lCell, fs); + lCurStr := FWorksheet.ReadAsText(lCell, fs); // if lCurStr = '' then lCurStr := ' '; // Check for invalid characters diff --git a/components/fpspreadsheet/xlsbiff8.pas b/components/fpspreadsheet/xlsbiff8.pas index 536934899..42c5a913c 100755 --- a/components/fpspreadsheet/xlsbiff8.pas +++ b/components/fpspreadsheet/xlsbiff8.pas @@ -499,7 +499,7 @@ var rtParams: TsRichTextParams; begin if FCommentPending then begin - commentStr := ReadWideString(AStream, FCommentLen, rtParams); + commentStr := Utf8Encode(ReadWideString(AStream, FCommentLen, rtParams)); if commentStr <> '' then begin comment := TBIFF8Comment.Create; @@ -2761,7 +2761,7 @@ begin if (cell = nil) or (AHyperlink^.Target='') then exit; - descr := AWorksheet.ReadAsUTF8Text(cell); // Hyperlink description + descr := AWorksheet.ReadAsText(cell); // Hyperlink description SplitHyperlink(AHyperlink^.Target, target, bookmark); u := ParseURI(AHyperlink^.Target); isInternal := (target = '') and (bookmark <> ''); diff --git a/components/fpspreadsheet/xlsxooxml.pas b/components/fpspreadsheet/xlsxooxml.pas index cee0790e4..dad241a4c 100755 --- a/components/fpspreadsheet/xlsxooxml.pas +++ b/components/fpspreadsheet/xlsxooxml.pas @@ -273,7 +273,7 @@ const {%H-}MIME_XML = 'application/xml'; MIME_RELS = 'application/vnd.openxmlformats-package.relationships+xml'; MIME_OFFICEDOCUMENT = 'application/vnd.openxmlformats-officedocument'; - MIME_CORE = 'application/vnd.openxmlformats-package.core-properties+xml'; +{%H-}MIME_CORE = 'application/vnd.openxmlformats-package.core-properties+xml'; MIME_SPREADML = MIME_OFFICEDOCUMENT + '.spreadsheetml'; MIME_SHEET = MIME_SPREADML + '.sheet.main+xml'; MIME_WORKSHEET = MIME_SPREADML + '.worksheet+xml'; @@ -2759,7 +2759,7 @@ begin end; if bookmark <> '' then //target = '' then s := Format('%s location="%s"', [s, bookmark]); - txt := UTF8TextToXMLText(AWorksheet.ReadAsUTF8Text(hyperlink^.Row, hyperlink^.Col)); + txt := UTF8TextToXMLText(AWorksheet.ReadAsText(hyperlink^.Row, hyperlink^.Col)); if (txt <> '') and (txt <> hyperlink^.Target) then s := Format('%s display="%s"', [s, txt]); if hyperlink^.ToolTip <> '' then begin