fpspreadsheet: Simplify clipboard access. Add format "Star Object Descriptor (XML)" for testing communication between LibreOffice and Clipboard.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@4368 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2015-10-04 16:08:00 +00:00
parent 6fb4bb9c9b
commit 6cb04bbcea
3 changed files with 97 additions and 90 deletions

View File

@ -1310,7 +1310,7 @@ begin
begin
w := FWorksheet.DefaultColWidth;
col := FWorksheet.FindCol(AColIndex);
if col <> nil then
if (col <> nil) and (col^.Width > 0) then
w := col^.Width;
end;
w := w * FWorkbook.GetDefaultFont.Size;

View File

@ -192,6 +192,7 @@ type
procedure AddBuiltinNumFormats; override;
procedure CreateStreams;
procedure DestroyStreams;
procedure InternalWriteToStream(AStream: TStream);
procedure ListAllColumnStyles;
procedure ListAllHeaderFooterFonts;
procedure ListAllNumFormats; override;
@ -233,6 +234,9 @@ type
procedure WriteToStream(AStream: TStream; AParam: Integer = 0); override;
end;
procedure WriteStarObjectDescriptorToStream(AStream: TStream);
implementation
uses
@ -354,6 +358,27 @@ type
end;
*)
{******************************************************************************}
{ Clipboard utility }
{******************************************************************************}
{@@ ----------------------------------------------------------------------------
Writes the "Star Object Descriptor". This is written to the clipboard by
Open/LibreOffice. No idea about the meaning of this...
-------------------------------------------------------------------------------}
procedure WriteStarObjectDescriptorToStream(AStream: TStream);
const
BYTES: packed array[0..$38] of byte = (
$39,$00,$00,$00,$CB,$B4,$BB,$47,$4C,$CE,$80,$4E,$A5,$91,$42,$D9,
$AE,$74,$95,$0F,$01,$00,$00,$00,$D2,$08,$00,$00,$C4,$01,$00,$00,
$00,$00,$00,$00,$00,$00,$00,$00,$05,$00,$63,$61,$6C,$63,$38,$00,
$00,$67,$45,$23,$01,$EF,$CD,$AB,$89);
begin
AStream.Write(BYTES, SizeOf(BYTES));
end;
{******************************************************************************}
{ TXMLHeaderFooterFont }
{******************************************************************************}
@ -3657,6 +3682,49 @@ begin
DestroyStream(FSMetaInfManifest);
end;
procedure TsSpreadOpenDocWriter.InternalWriteToStream(AStream: TStream);
var
FZip: TZipper;
begin
{ Analyze the workbook and collect all information needed }
ListAllNumFormats;
ListAllColumnStyles;
ListAllRowStyles;
ListAllHeaderFooterFonts;
{ Create the streams that will hold the file contents }
CreateStreams;
{ Fill the strings with the contents of the files }
WriteMimetype();
WriteMetaInfManifest();
WriteMeta();
WriteSettings();
WriteStyles();
WriteContent;
{ Now compress the files }
FZip := TZipper.Create;
try
FZip.FileName := '__temp__.tmp';
FZip.Entries.AddFileEntry(FSMeta, OPENDOC_PATH_META);
FZip.Entries.AddFileEntry(FSSettings, OPENDOC_PATH_SETTINGS);
FZip.Entries.AddFileEntry(FSStyles, OPENDOC_PATH_STYLES);
FZip.Entries.AddFileEntry(FSContent, OPENDOC_PATH_CONTENT);
FZip.Entries.AddFileEntry(FSMimetype, OPENDOC_PATH_MIMETYPE);
FZip.Entries.AddFileEntry(FSMetaInfManifest, OPENDOC_PATH_METAINF_MANIFEST);
ResetStreams;
FZip.SaveToStream(AStream);
finally
DestroyStreams;
FZip.Free;
end;
end;
procedure TsSpreadOpenDocWriter.ListAllColumnStyles;
var
i, j, c: Integer;
@ -4764,48 +4832,9 @@ end;
procedure TsSpreadOpenDocWriter.WriteToStream(AStream: TStream;
AParam: Integer = 0);
var
FZip: TZipper;
begin
Unused(AParam);
{ Analyze the workbook and collect all information needed }
ListAllNumFormats;
ListAllColumnStyles;
ListAllRowStyles;
ListAllHeaderFooterFonts;
{ Create the streams that will hold the file contents }
CreateStreams;
{ Fill the strings with the contents of the files }
WriteMimetype();
WriteMetaInfManifest();
WriteMeta();
WriteSettings();
WriteStyles();
WriteContent;
{ Now compress the files }
FZip := TZipper.Create;
try
FZip.FileName := '__temp__.tmp';
FZip.Entries.AddFileEntry(FSMeta, OPENDOC_PATH_META);
FZip.Entries.AddFileEntry(FSSettings, OPENDOC_PATH_SETTINGS);
FZip.Entries.AddFileEntry(FSStyles, OPENDOC_PATH_STYLES);
FZip.Entries.AddFileEntry(FSContent, OPENDOC_PATH_CONTENT);
FZip.Entries.AddFileEntry(FSMimetype, OPENDOC_PATH_MIMETYPE);
FZip.Entries.AddFileEntry(FSMetaInfManifest, OPENDOC_PATH_METAINF_MANIFEST);
ResetStreams;
FZip.SaveToStream(AStream);
finally
DestroyStreams;
FZip.Free;
end;
InternalWriteToStream(AStream);
end;
{ Writes an empty cell to the stream }
@ -6117,6 +6146,7 @@ begin
end;
end;
initialization
{@@ ----------------------------------------------------------------------------

View File

@ -468,7 +468,7 @@ implementation
uses
Types, Math, StrUtils, TypInfo, LCLType, LCLIntf, LCLProc,
Dialogs, Forms, Clipbrd,
fpsStrings, fpsUtils, fpsNumFormat, fpsHTMLUtils, fpsCSV;
fpsStrings, fpsUtils, fpsNumFormat, fpsHTMLUtils, fpsCSV, fpsOpenDocument;
var
cfBiff8Format: Integer = 0;
@ -477,6 +477,7 @@ var
cfTextHTMLFormat: Integer = 0;
cfCSVFormat: Integer = 0;
cfOpenDocumentFormat: Integer = 0;
cfStarObjectDescriptor: Integer = 0;
{@@ ----------------------------------------------------------------------------
Registers the spreadsheet components in the Lazarus component palette,
@ -1136,7 +1137,17 @@ var
sel: TsCellRangeArray;
stream: TStream;
savedCSVParams: TsCSVParams;
param: Integer;
procedure CopyToClipboard(AStream: TStream; AFileFormat: TsSpreadsheetFormat;
AClipboardFormat: Integer; AParam: Integer = 0);
begin
if AClipboardFormat = 0 then
exit;
FWorkbook.CopyToClipboardStream(AStream, AFileFormat, AParam);
Clipboard.AddFormat(AClipboardFormat, AStream);
(AStream as TMemoryStream).Clear;
end;
begin
sel := FWorksheet.GetSelection;
if Length(sel) = 0 then
@ -1149,82 +1160,47 @@ begin
stream := TMemoryStream.Create;
try
// Write OpenDocument format
FWorkbook.CopyToClipboardStream(stream, sfOpenDocument);
if cfOpenDocumentFormat <> 0 then
Clipboard.AddFormat(cfOpenDocumentFormat, stream);
CopyToClipboard(stream, sfOpenDocument, cfOpenDocumentFormat);
// Write OpenDocument's "Star Object Descriptor"
WriteStarObjectDescriptorToStream(stream);
if cfStarObjectDescriptor <> 0 then
Clipboard.AddFormat(cfStarObjectDescriptor, stream);
(stream as TMemoryStream).Clear;
// Write BIFF8 format
FWorkbook.CopyToClipboardStream(stream, sfExcel8);
if cfBiff8Format <> 0 then
Clipboard.AddFormat(cfBiff8Format, stream);
(stream as TMemoryStream).Clear;
CopyToClipboard(stream, sfExcel8, cfBiff8Format);
// Then write BIFF5 format
FWorkbook.CopyToClipboardStream(stream, sfExcel5);
if cfBiff5Format <> 0 then
Clipboard.AddFormat(cfBiff5Format, stream);
(stream as TMemoryStream).Clear;
CopyToClipboard(stream, sfExcel5, cfBiff5Format);
// Then write Windows HTML format
{$IFDEF MSWINDOWS}
param := PARAM_WINDOWS_CLIPBOARD_HTML;
FWorkbook.CopyToClipboardStream(stream, sfHTML, param);
if cfHtmlFormat <> 0 then
Clipboard.AddFormat(cfHTMLFormat, stream);
(stream as TMemoryStream).Clear;
CopyToClipboard(stream, sfHTML, cfHtmlFormat, PARAM_WINDOWS_CLIPBOARD_HTML);
{$ENDIF}
// Write standard html format (MIME-type "text/html")
FWorkbook.CopyToClipboardStream(stream, sfHTML);
if cfTextHtmlFormat <> 0 then
Clipboard.AddFormat(cfTextHTMLFormat, stream);
(stream as TMemoryStream).Clear;
CopyToClipboard(stream, sfHTML, cfTextHTMLFormat);
// Then write CSV format
savedCSVParams := CSVParams;
CsvParams.Delimiter := ';';
CsvParams.AutoDetectNumberFormat := false;
CsvParams.SheetIndex := FWorkbook.GetWorksheetIndex(FWorkbook.ActiveWorksheet);
FWorkbook.CopyToClipboardStream(stream, sfCSV);
if cfCSVFormat <> 0 then
Clipboard.AddFormat(cfCSVFormat, stream);
(stream as TMemoryStream).Clear;
CopyToClipboard(stream, sfCSV, cfCSVFormat);
// Finally write TEXT format
CsvParams.Delimiter := #9;
FWorkbook.CopyToClipboardStream(stream, sfCSV);
Clipboard.AddFormat(CF_TEXT, stream);
CopyToClipboard(stream, sfCSV, CF_TEXT);
CSVParams := savedCSVParams;
(stream as TMemoryStream).Clear;
// To do: XML format
// I don't know which format is written by xlsx and ods natively.
finally
stream.Free;
end;
finally
Clipboard.Close;
end;
(*
exit;
ClearCellClipboard;
for i:=0 to High(sel) do
for r := sel[i].Row1 to sel[i].Row2 do
for c := sel[i].Col1 to sel[i].Col2 do
begin
cell := FWorksheet.FindCell(r, c);
if cell = nil then
CellClipboard.AddEmptyCell(r, c)
else
CellClipboard.AddCell(cell);
end;
CellClipboard.MultipleRanges := (Length(sel) > 1);
*)
end;
{@@ ----------------------------------------------------------------------------
@ -3200,6 +3176,7 @@ initialization
{$ENDIF}
*)
cfOpenDocumentFormat := RegisterClipboardFormat('application/x-openoffice-embed-source-xml;windows_formatname="Star Embed Source (XML)"');
cfStarObjectDescriptor := RegisterClipboardFormat('application/x-openoffice-objectdescriptor-xml;windows_formatname="Star Object Descriptor (XML)"');
// cfOpenDocumentFormat := RegisterClipboardFormat('application/x-openoffice;windows_formatname="Star Embed Source (XML)"');
//cfOpenDocumentFormat := RegisterClipboardFormat('Star Embed Source (XML)');
// cfBiff8Format := RegisterClipboardFormat('application/vnd.ms-excel'); //Biff8');