From 5a4bb856f57912156ee853e84f224291b722efb7 Mon Sep 17 00:00:00 2001 From: wp_xxyyzz Date: Sun, 1 Mar 2015 12:23:14 +0000 Subject: [PATCH] fpspreadsheet: Fix TsWorksheet.CopyCell ignoring comments, hyperlinks and merged cells. Fix incorrect handling of trailing zeros of hyperlink strings when reading biff8. git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@3974 8e941d3f-bd1b-0410-a28a-d453659cc2b4 --- components/fpspreadsheet/fpspreadsheet.pas | 24 +++++++++++++++++++--- components/fpspreadsheet/xlsbiff8.pas | 7 +++++-- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/components/fpspreadsheet/fpspreadsheet.pas b/components/fpspreadsheet/fpspreadsheet.pas index e9333a88e..680cececc 100755 --- a/components/fpspreadsheet/fpspreadsheet.pas +++ b/components/fpspreadsheet/fpspreadsheet.pas @@ -205,9 +205,9 @@ type procedure UpdateCaches; { Reading of values } - function ReadAsUTF8Text(ARow, ACol: Cardinal): string; overload; //ansistring; overload; - function ReadAsUTF8Text(ACell: PCell): string; overload; //ansistring; overload; - function ReadAsUTF8Text(ACell: PCell; AFormatSettings: TFormatSettings): string; overload; //ansistring; overload; + function ReadAsUTF8Text(ARow, ACol: Cardinal): string; overload; + function ReadAsUTF8Text(ACell: PCell): string; overload; + function ReadAsUTF8Text(ACell: PCell; AFormatSettings: TFormatSettings): string; overload; function ReadAsNumber(ARow, ACol: Cardinal): Double; overload; function ReadAsNumber(ACell: PCell): Double; overload; function ReadAsDateTime(ARow, ACol: Cardinal; out AResult: TDateTime): Boolean; overload; @@ -1882,6 +1882,8 @@ end; procedure TsWorksheet.CopyCell(AFromCell, AToCell: PCell); var toRow, toCol: Cardinal; + row1, col1, row2, col2: Cardinal; + hyperlink: PsHyperlink; begin if (AFromCell = nil) or (AToCell = nil) then exit; @@ -1901,6 +1903,22 @@ begin // This also fires the OnChange event. CopyFormula(AFromCell, AToCell); + // Merged? + if IsMergeBase(AFromCell) then + begin + FindMergedRange(AFromCell, row1, col1, row2, col2); + MergeCells(toRow, toCol, toRow + row2 - row1, toCol + col2 - col1); + end; + + // Copy comment + if HasComment(AFromCell) then + WriteComment(AToCell, ReadComment(AFromCell)); + + // Copy hyperlink + hyperlink := FindHyperlink(AFromCell); + if hyperlink <> nil then + WriteHyperlink(AToCell, hyperlink^.Target, hyperlink^.Tooltip); + // Notify visual controls of possibly changed row heights. ChangedFont(AToCell^.Row, AToCell^.Col); end; diff --git a/components/fpspreadsheet/xlsbiff8.pas b/components/fpspreadsheet/xlsbiff8.pas index bd8bc8bba..c9675181b 100755 --- a/components/fpspreadsheet/xlsbiff8.pas +++ b/components/fpspreadsheet/xlsbiff8.pas @@ -1468,7 +1468,6 @@ begin { Target frame: external link (URI or local file) } link := ''; if flags and MASK_HLINK_LINK <> 0 then -// if flags and (MASK_HLINK_LINK or MASK_HLINK_ABSOLUTE) = (MASK_HLINK_LINK or MASK_HLINK_ABSOLUTE) then begin AStream.ReadBuffer(guid, SizeOf(guid)); @@ -1480,6 +1479,7 @@ begin // Character array of URL (16-bit-characters, with trailing zero word) SetLength(wideStr, len); AStream.ReadBuffer(wideStr[1], len*SizeOf(wideChar)); + SetLength(wideStr, len-1); // Remove trailing zero word link := UTF8Encode(wideStr); end else // Check for local file @@ -1490,9 +1490,10 @@ begin len := DWordLEToN(AStream.ReadDWord); // Character array of the shortened file path and name in 8.3-DOS-format. // This field can be filled with a long file name too. - // No Unicode string header, always 8-bit characters, zeroterminated. + // No unicode string header, always 8-bit characters, zero-terminated. SetLength(ansiStr, len); AStream.ReadBuffer(ansiStr[1], len*SizeOf(ansiChar)); + SetLength(ansistr, len-1); // Remove trailing zero linkDos := AnsiToUTF8(ansiStr); while dirUpCount > 0 do begin @@ -1535,6 +1536,7 @@ begin // no Unicode string header, always 16-bit characters, zero-terminated SetLength(wideStr, len); AStream.ReadBuffer(wideStr[1], len*SizeOf(wideChar)); + SetLength(wideStr, len-1); // Remove trailing zero word mark := UTF8Encode(wideStr); end; @@ -1576,6 +1578,7 @@ begin numbytes := RecordSize - 5*SizeOf(word); SetLength(wideStr, numbytes div 2); AStream.ReadBuffer(wideStr[1], numbytes); + SetLength(wideStr, Length(wideStr)-1); // Remove trailing zero word txt := UTF8Encode(wideStr); { Add tooltip to hyperlinks }