You've already forked lazarus-ccr
fpspreadsheet: Add code for copying to clipboard (fpsCtrls), initial version only handles biff8 and biff5 formats.
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@4354 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -591,6 +591,9 @@ type
|
|||||||
{@@ The workbook contains the worksheets and provides methods for reading from
|
{@@ The workbook contains the worksheets and provides methods for reading from
|
||||||
and writing to file.
|
and writing to file.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{ TsWorkbook }
|
||||||
|
|
||||||
TsWorkbook = class
|
TsWorkbook = class
|
||||||
private
|
private
|
||||||
{ Internal data }
|
{ Internal data }
|
||||||
@ -653,7 +656,8 @@ type
|
|||||||
class function GetFormatFromFileHeader(AStream: TStream;
|
class function GetFormatFromFileHeader(AStream: TStream;
|
||||||
out SheetType: TsSpreadsheetFormat): Boolean; overload;
|
out SheetType: TsSpreadsheetFormat): Boolean; overload;
|
||||||
function CreateSpreadReader(AFormat: TsSpreadsheetFormat): TsBasicSpreadReader;
|
function CreateSpreadReader(AFormat: TsSpreadsheetFormat): TsBasicSpreadReader;
|
||||||
function CreateSpreadWriter(AFormat: TsSpreadsheetFormat): TsBasicSpreadWriter;
|
function CreateSpreadWriter(AFormat: TsSpreadsheetFormat;
|
||||||
|
AClipboardMode: Boolean = false): TsBasicSpreadWriter;
|
||||||
procedure ReadFromFile(AFileName: string; AFormat: TsSpreadsheetFormat); overload;
|
procedure ReadFromFile(AFileName: string; AFormat: TsSpreadsheetFormat); overload;
|
||||||
procedure ReadFromFile(AFileName: string); overload;
|
procedure ReadFromFile(AFileName: string); overload;
|
||||||
procedure ReadFromFileIgnoringExtension(AFileName: string);
|
procedure ReadFromFileIgnoringExtension(AFileName: string);
|
||||||
@ -662,7 +666,7 @@ type
|
|||||||
const AFormat: TsSpreadsheetFormat;
|
const AFormat: TsSpreadsheetFormat;
|
||||||
const AOverwriteExisting: Boolean = False); overload;
|
const AOverwriteExisting: Boolean = False); overload;
|
||||||
procedure WriteToFile(const AFileName: String; const AOverwriteExisting: Boolean = False); overload;
|
procedure WriteToFile(const AFileName: String; const AOverwriteExisting: Boolean = False); overload;
|
||||||
procedure WriteToStream(AStream: TStream; AFormat: TsSpreadsheetFormat);
|
procedure WriteToStream(AStream: TStream; AFormat: TsSpreadsheetFormat; AClipboardMode: Boolean = false);
|
||||||
|
|
||||||
{ Worksheet list handling methods }
|
{ Worksheet list handling methods }
|
||||||
function AddWorksheet(AName: string;
|
function AddWorksheet(AName: string;
|
||||||
@ -720,6 +724,9 @@ type
|
|||||||
function AddNumberFormat(AFormatStr: String): Integer;
|
function AddNumberFormat(AFormatStr: String): Integer;
|
||||||
function GetNumberFormat(AIndex: Integer): TsNumFormatParams;
|
function GetNumberFormat(AIndex: Integer): TsNumFormatParams;
|
||||||
function GetNumberFormatCount: Integer;
|
function GetNumberFormatCount: Integer;
|
||||||
|
|
||||||
|
{ Clipboard }
|
||||||
|
procedure CopyToClipboardStream(AStream: TStream; AFormat: TsSpreadsheetFormat);
|
||||||
(*
|
(*
|
||||||
{ Color handling }
|
{ Color handling }
|
||||||
function FPSColorToHexString(AColor: TsColor; ARGBColor: TFPColor): String;
|
function FPSColorToHexString(AColor: TsColor; ARGBColor: TFPColor): String;
|
||||||
@ -810,6 +817,7 @@ type
|
|||||||
TsBasicSpreadReader = class(TsBasicSpreadReaderWriter)
|
TsBasicSpreadReader = class(TsBasicSpreadReaderWriter)
|
||||||
public
|
public
|
||||||
{ General writing methods }
|
{ General writing methods }
|
||||||
|
procedure ReadFromClipboardStream(AStream: TStream); virtual; abstract;
|
||||||
procedure ReadFromFile(AFileName: string); virtual; abstract;
|
procedure ReadFromFile(AFileName: string); virtual; abstract;
|
||||||
procedure ReadFromStream(AStream: TStream); virtual; abstract;
|
procedure ReadFromStream(AStream: TStream); virtual; abstract;
|
||||||
procedure ReadFromStrings(AStrings: TStrings); virtual; abstract;
|
procedure ReadFromStrings(AStrings: TStrings); virtual; abstract;
|
||||||
@ -821,6 +829,7 @@ type
|
|||||||
{ Helpers }
|
{ Helpers }
|
||||||
procedure CheckLimitations; virtual;
|
procedure CheckLimitations; virtual;
|
||||||
{ General writing methods }
|
{ General writing methods }
|
||||||
|
procedure WriteToClipboardStream(AStream: TStream); virtual; abstract;
|
||||||
procedure WriteToFile(const AFileName: string;
|
procedure WriteToFile(const AFileName: string;
|
||||||
const AOverwriteExisting: Boolean = False); virtual; abstract;
|
const AOverwriteExisting: Boolean = False); virtual; abstract;
|
||||||
procedure WriteToStream(AStream: TStream); virtual; abstract;
|
procedure WriteToStream(AStream: TStream); virtual; abstract;
|
||||||
@ -6618,19 +6627,23 @@ end;
|
|||||||
Convenience method which creates the correct writer object for a given
|
Convenience method which creates the correct writer object for a given
|
||||||
spreadsheet format.
|
spreadsheet format.
|
||||||
|
|
||||||
@param AFormat File format to be used for writing the workbook
|
@param AFormat File format to be used for writing the workbook
|
||||||
|
@param AClipboardMode If TRUE then special data are written for usage in the
|
||||||
|
clipboard
|
||||||
|
|
||||||
@return An instance of a TsCustomSpreadWriter descendent which is able to
|
@return An instance of a TsCustomSpreadWriter descendent which is able to
|
||||||
write the given file format.
|
write the given file format.
|
||||||
-------------------------------------------------------------------------------}
|
-------------------------------------------------------------------------------}
|
||||||
function TsWorkbook.CreateSpreadWriter(AFormat: TsSpreadsheetFormat): TsBasicSpreadWriter;
|
function TsWorkbook.CreateSpreadWriter(AFormat: TsSpreadsheetFormat;
|
||||||
|
AClipboardMode: Boolean = false): TsBasicSpreadWriter;
|
||||||
var
|
var
|
||||||
i: Integer;
|
i: Integer;
|
||||||
begin
|
begin
|
||||||
Result := nil;
|
Result := nil;
|
||||||
|
|
||||||
for i := 0 to Length(GsSpreadFormats) - 1 do
|
for i := 0 to Length(GsSpreadFormats) - 1 do
|
||||||
if GsSpreadFormats[i].Format = AFormat then
|
if (GsSpreadFormats[i].Format = AFormat) and
|
||||||
|
(AClipboardMode or GsSpreadFormats[i].CanWriteToClipboard) then
|
||||||
begin
|
begin
|
||||||
Result := GsSpreadFormats[i].WriterClass.Create(self);
|
Result := GsSpreadFormats[i].WriterClass.Create(self);
|
||||||
Break;
|
Break;
|
||||||
@ -6890,19 +6903,23 @@ end;
|
|||||||
{@@ ----------------------------------------------------------------------------
|
{@@ ----------------------------------------------------------------------------
|
||||||
Writes the document to a stream
|
Writes the document to a stream
|
||||||
|
|
||||||
@param AStream Instance of the stream being written to
|
@param AStream Instance of the stream being written to
|
||||||
@param AFormat File format to be written.
|
@param AFormat File format to be written.
|
||||||
|
@param AClipboardMode Stream will be used by calling method for clipboard access
|
||||||
-------------------------------------------------------------------------------}
|
-------------------------------------------------------------------------------}
|
||||||
procedure TsWorkbook.WriteToStream(AStream: TStream; AFormat: TsSpreadsheetFormat);
|
procedure TsWorkbook.WriteToStream(AStream: TStream; AFormat: TsSpreadsheetFormat;
|
||||||
|
AClipboardMode: Boolean = false);
|
||||||
var
|
var
|
||||||
AWriter: TsBasicSpreadWriter;
|
AWriter: TsBasicSpreadWriter;
|
||||||
begin
|
begin
|
||||||
AWriter := CreateSpreadWriter(AFormat);
|
AWriter := CreateSpreadWriter(AFormat, AClipboardMode);
|
||||||
try
|
try
|
||||||
PrepareBeforeSaving;
|
PrepareBeforeSaving;
|
||||||
AWriter.CheckLimitations;
|
AWriter.CheckLimitations;
|
||||||
FReadWriteFlag := rwfWrite;
|
FReadWriteFlag := rwfWrite;
|
||||||
AWriter.WriteToStream(AStream);
|
if AClipboardMode then
|
||||||
|
AWriter.WriteToClipboardStream(AStream) else
|
||||||
|
AWriter.WriteToStream(AStream);
|
||||||
finally
|
finally
|
||||||
FReadWriteFlag := rwfNormal;
|
FReadWriteFlag := rwfNormal;
|
||||||
AWriter.Free;
|
AWriter.Free;
|
||||||
@ -7715,6 +7732,60 @@ function TsWorkbook.GetNumberFormatCount: Integer;
|
|||||||
begin
|
begin
|
||||||
Result := FNumFormatList.Count;
|
Result := FNumFormatList.Count;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{@@ ----------------------------------------------------------------------------
|
||||||
|
Writes the selected cells to a stream for usage in the clipboard.
|
||||||
|
Transfer to the clipboard has do be done by the calling routine since
|
||||||
|
fpspreadsheet does not "know" the system's clipboard.
|
||||||
|
-------------------------------------------------------------------------------}
|
||||||
|
procedure TsWorkbook.CopyToClipboardStream(AStream: TStream;
|
||||||
|
AFormat: TsSpreadsheetFormat);
|
||||||
|
var
|
||||||
|
clipbook: TsWorkbook;
|
||||||
|
clipsheet: TsWorksheet;
|
||||||
|
sel: TsCellRange;
|
||||||
|
r, c: Cardinal;
|
||||||
|
srccell, destcell: PCell;
|
||||||
|
begin
|
||||||
|
if AStream = nil then
|
||||||
|
exit;
|
||||||
|
|
||||||
|
if ActiveWorksheet = nil then
|
||||||
|
exit;
|
||||||
|
|
||||||
|
// Create workbook which will be written to clipboard stream
|
||||||
|
// Contains only the selected worksheet and the selected cells.
|
||||||
|
clipbook := TsWorkbook.Create;
|
||||||
|
try
|
||||||
|
clipsheet := clipbook.AddWorksheet(ActiveWorksheet.Name);
|
||||||
|
for sel in ActiveWorksheet.GetSelection do
|
||||||
|
begin
|
||||||
|
for r := sel.Row1 to sel.Row2 do
|
||||||
|
for c := sel.Col1 to sel.Col2 do
|
||||||
|
begin
|
||||||
|
srccell := ActiveWorksheet.FindCell(r, c);
|
||||||
|
if srccell <> nil then begin
|
||||||
|
destcell := clipsheet.AddCell(r, c);
|
||||||
|
clipsheet.CopyCell(srccell, destcell);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
// Select the same cells as in the source workbook.
|
||||||
|
clipsheet.SetSelection(ActiveWorksheet.GetSelection);
|
||||||
|
clipsheet.SelectCell(ActiveWorksheet.ActiveCellRow, ActiveWorksheet.ActiveCellCol);
|
||||||
|
|
||||||
|
// Write this workbook to a stream. Set the last parameter (ClipboardMode)
|
||||||
|
// to TRUE to use the dedicated clipboard routine.
|
||||||
|
clipbook.WriteToStream(AStream, AFormat, true);
|
||||||
|
|
||||||
|
// The calling routine which copies the stream to the clipboard requires
|
||||||
|
// the stream to be at its beginning.
|
||||||
|
AStream.Position := 0;
|
||||||
|
finally
|
||||||
|
clipbook.Free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
(*
|
(*
|
||||||
{@@ ----------------------------------------------------------------------------
|
{@@ ----------------------------------------------------------------------------
|
||||||
Adds a color to the palette and returns its palette index, but only if the
|
Adds a color to the palette and returns its palette index, but only if the
|
||||||
|
@ -467,9 +467,13 @@ procedure Register;
|
|||||||
implementation
|
implementation
|
||||||
|
|
||||||
uses
|
uses
|
||||||
Types, Math, StrUtils, TypInfo, LCLType, LCLProc, Dialogs, Forms,
|
Types, Math, StrUtils, TypInfo, LCLType, LCLProc, Dialogs, Forms, Clipbrd,
|
||||||
fpsStrings, fpsUtils, fpsNumFormat, fpsHTMLUtils;
|
fpsStrings, fpsUtils, fpsNumFormat, fpsHTMLUtils;
|
||||||
|
|
||||||
|
var
|
||||||
|
cfBiff8Format: Integer = 0;
|
||||||
|
cfBiff5Format: Integer = 0;
|
||||||
|
|
||||||
{@@ ----------------------------------------------------------------------------
|
{@@ ----------------------------------------------------------------------------
|
||||||
Registers the spreadsheet components in the Lazarus component palette,
|
Registers the spreadsheet components in the Lazarus component palette,
|
||||||
page "FPSpreadsheet".
|
page "FPSpreadsheet".
|
||||||
@ -1145,7 +1149,43 @@ var
|
|||||||
r,c,i: Integer;
|
r,c,i: Integer;
|
||||||
sel: TsCellRangeArray;
|
sel: TsCellRangeArray;
|
||||||
cell: PCell;
|
cell: PCell;
|
||||||
|
stream: TStream;
|
||||||
begin
|
begin
|
||||||
|
Clipboard.Open;
|
||||||
|
try
|
||||||
|
Clipboard.Clear;
|
||||||
|
|
||||||
|
// Ensure the 'Biff8' clipboard format is registered
|
||||||
|
cfBiff8Format := Clipboard.FindFormatID('Biff8');
|
||||||
|
If cfBiff8Format = 0 Then
|
||||||
|
cfBiff8Format := RegisterClipboardFormat('Biff8');
|
||||||
|
|
||||||
|
// Ensure that the 'Biff5' clipboard format is registered
|
||||||
|
cfBiff5Format := Clipboard.FindFormatID('Biff5');
|
||||||
|
If cfBiff5Format = 0 Then
|
||||||
|
cfBiff5Format := RegisterClipboardFormat('Biff5');
|
||||||
|
|
||||||
|
stream := TMemoryStream.Create;
|
||||||
|
try
|
||||||
|
// At first write BIFF8 format
|
||||||
|
FWorkbook.CopyToClipboardStream(stream, sfExcel8);
|
||||||
|
Clipboard.AddFormat(cfBiff8Format, stream);
|
||||||
|
(stream as TMemoryStream).Clear;
|
||||||
|
|
||||||
|
// Then write BIFF5 format
|
||||||
|
FWorkbook.CopyToClipboardStream(stream, sfExcel5);
|
||||||
|
Clipboard.AddFormat(cfBiff5Format, stream);
|
||||||
|
|
||||||
|
// To do: HTML format, CSV format, XML format
|
||||||
|
// I don't know which format is written by xlsx and ods natively.
|
||||||
|
finally
|
||||||
|
stream.Free;
|
||||||
|
end;
|
||||||
|
finally
|
||||||
|
Clipboard.Close;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
FCutPending := false;
|
FCutPending := false;
|
||||||
|
|
||||||
ClearCellClipboard;
|
ClearCellClipboard;
|
||||||
|
@ -141,13 +141,16 @@ type
|
|||||||
ReaderClass: TsSpreadReaderClass;
|
ReaderClass: TsSpreadReaderClass;
|
||||||
WriterClass: TsSpreadWriterClass;
|
WriterClass: TsSpreadWriterClass;
|
||||||
Format: TsSpreadsheetFormat;
|
Format: TsSpreadsheetFormat;
|
||||||
|
CanReadFromClipboard: Boolean;
|
||||||
|
CanWriteToClipboard: Boolean;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
var
|
var
|
||||||
GsSpreadFormats: array of TsSpreadFormatData;
|
GsSpreadFormats: array of TsSpreadFormatData;
|
||||||
|
|
||||||
procedure RegisterSpreadFormat(AReaderClass: TsSpreadReaderClass;
|
procedure RegisterSpreadFormat(AReaderClass: TsSpreadReaderClass;
|
||||||
AWriterClass: TsSpreadWriterClass; AFormat: TsSpreadsheetFormat);
|
AWriterClass: TsSpreadWriterClass; AFormat: TsSpreadsheetFormat;
|
||||||
|
ACanReadFromClipboard: Boolean = false; ACanWriteToClipboard: Boolean = false);
|
||||||
|
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
@ -162,7 +165,9 @@ uses
|
|||||||
procedure RegisterSpreadFormat(
|
procedure RegisterSpreadFormat(
|
||||||
AReaderClass: TsSpreadReaderClass;
|
AReaderClass: TsSpreadReaderClass;
|
||||||
AWriterClass: TsSpreadWriterClass;
|
AWriterClass: TsSpreadWriterClass;
|
||||||
AFormat: TsSpreadsheetFormat);
|
AFormat: TsSpreadsheetFormat;
|
||||||
|
ACanReadFromClipboard: Boolean = false;
|
||||||
|
ACanWriteToClipboard: Boolean = false);
|
||||||
var
|
var
|
||||||
len: Integer;
|
len: Integer;
|
||||||
begin
|
begin
|
||||||
@ -172,6 +177,8 @@ begin
|
|||||||
GsSpreadFormats[len].ReaderClass := AReaderClass;
|
GsSpreadFormats[len].ReaderClass := AReaderClass;
|
||||||
GsSpreadFormats[len].WriterClass := AWriterClass;
|
GsSpreadFormats[len].WriterClass := AWriterClass;
|
||||||
GsSpreadFormats[len].Format := AFormat;
|
GsSpreadFormats[len].Format := AFormat;
|
||||||
|
GsSpreadFormats[len].CanReadFromClipboard := ACanReadFromClipboard;
|
||||||
|
GsSpreadFormats[len].CanWriteToClipboard := ACanWriteToClipboard;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
@ -1807,7 +1807,7 @@ initialization
|
|||||||
Excel5Settings.CodePage := GetDefaultTextEncoding;
|
Excel5Settings.CodePage := GetDefaultTextEncoding;
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
|
|
||||||
RegisterSpreadFormat(TsSpreadBIFF5Reader, TsSpreadBIFF5Writer, sfExcel5);
|
RegisterSpreadFormat(TsSpreadBIFF5Reader, TsSpreadBIFF5Writer, sfExcel5, false, true);
|
||||||
MakeLEPalette(PALETTE_BIFF5);
|
MakeLEPalette(PALETTE_BIFF5);
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
@ -3443,7 +3443,7 @@ end;
|
|||||||
initialization
|
initialization
|
||||||
|
|
||||||
// Registers this reader / writer in fpSpreadsheet
|
// Registers this reader / writer in fpSpreadsheet
|
||||||
RegisterSpreadFormat(TsSpreadBIFF8Reader, TsSpreadBIFF8Writer, sfExcel8);
|
RegisterSpreadFormat(TsSpreadBIFF8Reader, TsSpreadBIFF8Writer, sfExcel8, false, true);
|
||||||
|
|
||||||
// Converts the palette to litte-endian
|
// Converts the palette to litte-endian
|
||||||
MakeLEPalette(PALETTE_BIFF8);
|
MakeLEPalette(PALETTE_BIFF8);
|
||||||
|
@ -463,6 +463,8 @@ type
|
|||||||
FCodePage: String; // in a format prepared for lconvencoding.ConvertEncoding
|
FCodePage: String; // in a format prepared for lconvencoding.ConvertEncoding
|
||||||
FFirstNumFormatIndexInFile: Integer;
|
FFirstNumFormatIndexInFile: Integer;
|
||||||
FPalette: TsPalette;
|
FPalette: TsPalette;
|
||||||
|
FClipboardMode: Boolean;
|
||||||
|
|
||||||
procedure AddBuiltinNumFormats; override;
|
procedure AddBuiltinNumFormats; override;
|
||||||
function FindXFIndex(ACell: PCell): Integer; virtual;
|
function FindXFIndex(ACell: PCell): Integer; virtual;
|
||||||
function FixLineEnding(const AText: String): String;
|
function FixLineEnding(const AText: String): String;
|
||||||
@ -571,6 +573,7 @@ type
|
|||||||
constructor Create(AWorkbook: TsWorkbook); override;
|
constructor Create(AWorkbook: TsWorkbook); override;
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
procedure CheckLimitations; override;
|
procedure CheckLimitations; override;
|
||||||
|
procedure WriteToClipboardStream(AStream: TStream); override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure AddBuiltinBiffFormats(AList: TStringList;
|
procedure AddBuiltinBiffFormats(AList: TStringList;
|
||||||
@ -3945,6 +3948,10 @@ begin
|
|||||||
AStream.WriteWord(WordToLE(w));
|
AStream.WriteWord(WordToLE(w));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TsSpreadBIFFWriter.WriteToClipboardStream(AStream: TStream);
|
||||||
|
begin
|
||||||
|
WriteToStream(AStream);
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TsSpreadBIFFWriter.WriteVirtualCells(AStream: TStream);
|
procedure TsSpreadBIFFWriter.WriteVirtualCells(AStream: TStream);
|
||||||
var
|
var
|
||||||
|
Reference in New Issue
Block a user