You've already forked lazarus-ccr
fpspreadsheet: Improved cooperation of visual controls with clipboard.
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@4363 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -348,6 +348,7 @@ type
|
||||
procedure AcShowGridLinesExecute(Sender: TObject);
|
||||
procedure AcShowGridLinesUpdate(Sender: TObject);
|
||||
procedure AcViewInspectorExecute(Sender: TObject);
|
||||
procedure EditCut1Execute(Sender: TObject);
|
||||
procedure HyperlinkHandler(Sender: TObject; ACaption: String;
|
||||
var AHyperlink: TsHyperlink);
|
||||
procedure InspectorTabControlChange(Sender: TObject);
|
||||
@ -581,6 +582,11 @@ begin
|
||||
InspectorSplitter.Left := 0; // Make sure that the splitter is always at the left of the inspector
|
||||
end;
|
||||
|
||||
procedure TMainForm.EditCut1Execute(Sender: TObject);
|
||||
begin
|
||||
//
|
||||
end;
|
||||
|
||||
{ Event handler for hyperlinks: it only has to provide the hyperlink data
|
||||
which are applied to the active cell by the TsCellHyperlinkAction.
|
||||
Is called by the "new hyperlink" and "edit hyperlink" actions.
|
||||
|
@ -118,6 +118,7 @@ type
|
||||
FCopyMode: TsCopyMode;
|
||||
public
|
||||
procedure ExecuteTarget(Target: TObject); override;
|
||||
function HandlesTarget(Target: TObject): Boolean; override;
|
||||
procedure UpdateTarget(Target: TObject); override;
|
||||
published
|
||||
property Caption;
|
||||
@ -525,7 +526,7 @@ implementation
|
||||
|
||||
uses
|
||||
StdCtrls, ExtCtrls, Buttons, Forms,
|
||||
fpsUtils, fpsNumFormat, fpsVisualUtils;
|
||||
fpsUtils, fpsNumFormat, fpsVisualUtils, fpSpreadsheetGrid;
|
||||
|
||||
procedure Register;
|
||||
begin
|
||||
@ -767,28 +768,47 @@ const
|
||||
coCopyFormat, coCopyValue, coCopyFormula, coCopyCell
|
||||
);
|
||||
begin
|
||||
Unused(Target);
|
||||
if Target is TsCustomWorksheetGrid then
|
||||
case FCopyMode of
|
||||
cmBrush:
|
||||
begin
|
||||
Checked := true;
|
||||
WorkbookSource.SetPendingOperation(OPERATIONS[FCopyItem], Worksheet.GetSelection);
|
||||
end;
|
||||
cmCopy:
|
||||
begin
|
||||
Checked := false;
|
||||
WorkbookSource.CopyCellsToClipboard;
|
||||
end;
|
||||
cmCut:
|
||||
begin
|
||||
Checked := false;
|
||||
WorkbookSource.CutCellsToClipboard;
|
||||
end;
|
||||
cmPaste:
|
||||
begin
|
||||
Checked := false;
|
||||
WorkbookSource.PasteCellsFromClipboard(OPERATIONS[FCopyItem]);
|
||||
end;
|
||||
end
|
||||
else
|
||||
if Target is TCustomEdit then
|
||||
case FCopyMode of
|
||||
cmBrush : ;
|
||||
cmCopy : (Target as TCustomEdit).CopyToClipboard;
|
||||
cmCut : (Target as TCustomEdit).CutToClipboard;
|
||||
cmPaste : (Target as TCustomEdit).PasteFromClipboard;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TsCopyAction.HandlesTarget(Target: TObject): Boolean;
|
||||
begin
|
||||
case FCopyMode of
|
||||
cmBrush:
|
||||
begin
|
||||
Checked := true;
|
||||
WorkbookSource.SetPendingOperation(OPERATIONS[FCopyItem], Worksheet.GetSelection);
|
||||
end;
|
||||
cmCopy:
|
||||
begin
|
||||
Checked := false;
|
||||
WorkbookSource.CopyCellsToClipboard;
|
||||
end;
|
||||
cmCut:
|
||||
begin
|
||||
Checked := false;
|
||||
WorkbookSource.CutCellsToClipboard;
|
||||
end;
|
||||
cmPaste:
|
||||
begin
|
||||
Checked := false;
|
||||
WorkbookSource.PasteCellsFromClipboard(OPERATIONS[FCopyItem]);
|
||||
end;
|
||||
cmBrush: Result := inherited HandlesTarget(Target);
|
||||
cmCopy,
|
||||
cmCut,
|
||||
cmPaste: Result := (Target <> nil) and
|
||||
( (Target is TsCustomWorksheetGrid) or (Target is TCustomEdit) );
|
||||
end;
|
||||
end;
|
||||
|
||||
|
@ -22,6 +22,7 @@ type
|
||||
procedure ReadNumber(AStream: TStream); override;
|
||||
public
|
||||
constructor Create(AWorkbook: TsWorkbook); override;
|
||||
procedure ReadFromClipboardStream(AStream: TStream); override;
|
||||
procedure ReadFromFile(AFileName: String); override;
|
||||
procedure ReadFromStream(AStream: TStream); override;
|
||||
procedure ReadFromStrings(AStrings: TStrings); override;
|
||||
@ -200,6 +201,11 @@ begin
|
||||
Unused(AStream);
|
||||
end;
|
||||
|
||||
procedure TsCSVReader.ReadFromClipboardStream(AStream: TStream);
|
||||
begin
|
||||
ReadFromStream(AStream);
|
||||
end;
|
||||
|
||||
procedure TsCSVReader.ReadFromFile(AFileName: String);
|
||||
begin
|
||||
FWorksheetName := ChangeFileExt(ExtractFileName(AFileName), '');
|
||||
@ -372,9 +378,10 @@ end;
|
||||
procedure TsCSVWriter.WriteSheet(AStream: TStream; AWorksheet: TsWorksheet);
|
||||
var
|
||||
r: Cardinal;
|
||||
FirstRow: Cardinal;
|
||||
LastRow: Cardinal;
|
||||
firstRow: Cardinal;
|
||||
lastRow: Cardinal;
|
||||
cell: PCell;
|
||||
n: Integer;
|
||||
begin
|
||||
FWorksheet := AWorksheet;
|
||||
|
||||
@ -385,15 +392,23 @@ begin
|
||||
FCSVBuilder.QuoteChar := CSVParams.QuoteChar;
|
||||
FCSVBuilder.SetOutput(AStream);
|
||||
|
||||
if FClipboardMode then
|
||||
FirstRow := FWorksheet.GetFirstRowIndex else
|
||||
FirstRow := 0;
|
||||
LastRow := FWorksheet.GetLastOccupiedRowIndex;
|
||||
for r := FirstRow to LastRow do
|
||||
n := FWorksheet.GetCellCount;
|
||||
if FClipboardMode and (n = 1) then
|
||||
begin
|
||||
for cell in FWorksheet.Cells.GetRowEnumerator(r) do
|
||||
WriteCellToStream(AStream, cell);
|
||||
FCSVBuilder.AppendRow;
|
||||
cell := FWorksheet.Cells.GetFirstCell;
|
||||
WriteCellToStream(AStream, cell);
|
||||
end else
|
||||
begin
|
||||
if FClipboardMode then
|
||||
firstRow := FWorksheet.GetFirstRowIndex else
|
||||
firstRow := 0;
|
||||
lastRow := FWorksheet.GetLastOccupiedRowIndex;
|
||||
for r := firstRow to lastRow do
|
||||
begin
|
||||
for cell in FWorksheet.Cells.GetRowEnumerator(r) do
|
||||
WriteCellToStream(AStream, cell);
|
||||
FCSVBuilder.AppendRow;
|
||||
end;
|
||||
end;
|
||||
finally
|
||||
FreeAndNil(FCSVBuilder);
|
||||
@ -433,7 +448,7 @@ end;
|
||||
|
||||
initialization
|
||||
InitFormatSettings(CSVParams.FormatSettings);
|
||||
RegisterSpreadFormat(TsCSVReader, TsCSVWriter, sfCSV, false, true);
|
||||
RegisterSpreadFormat(TsCSVReader, TsCSVWriter, sfCSV, true, true);
|
||||
|
||||
end.
|
||||
|
||||
|
@ -1601,6 +1601,10 @@ begin
|
||||
toRow := AToCell^.Row;
|
||||
toCol := AToCell^.Col;
|
||||
|
||||
// Avoid misplaced notifications during the copy operations when things could
|
||||
// not yet be in place.
|
||||
FWorkbook.DisableNotifications;
|
||||
|
||||
// Copy cell values
|
||||
AToCell^ := AFromCell^;
|
||||
|
||||
@ -1648,6 +1652,11 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
FWorkbook.EnableNotifications;
|
||||
|
||||
// Notify visual controls of changes
|
||||
ChangedCell(AToCell^.Row, AToCell^.Col);
|
||||
|
||||
// Notify visual controls of possibly changed row heights.
|
||||
ChangedFont(AToCell^.Row, AToCell^.Col);
|
||||
end;
|
||||
@ -7876,27 +7885,30 @@ begin
|
||||
end;
|
||||
// Select the same cells as in the clipboard
|
||||
n := clipsheet.GetSelectionCount;
|
||||
SetLength(selArray, n);
|
||||
for i := 0 to n-1 do
|
||||
begin
|
||||
sel := clipsheet.GetSelection[i];
|
||||
selArray[i].Row1 := sel.Row1 + dr;
|
||||
selArray[i].Col1 := sel.Col1 + dc;
|
||||
selArray[i].Row2 := sel.Row2 + dr;
|
||||
selArray[i].Col2 := sel.Col2 + dc;
|
||||
if n > 0 then
|
||||
begin
|
||||
SetLength(selArray, n);
|
||||
for i := 0 to n-1 do
|
||||
begin
|
||||
sel := clipsheet.GetSelection[i];
|
||||
selArray[i].Row1 := sel.Row1 + dr;
|
||||
selArray[i].Col1 := sel.Col1 + dc;
|
||||
selArray[i].Row2 := sel.Row2 + dr;
|
||||
selArray[i].Col2 := sel.Col2 + dc;
|
||||
end;
|
||||
ActiveWorksheet.SetSelection(selArray);
|
||||
// Select active cell. If not found in the file, let's use the last cell of the selections
|
||||
if (clipsheet.ActiveCellRow <> 0) and (clipsheet.ActiveCellCol <> 0) then
|
||||
begin
|
||||
r := clipsheet.ActiveCellRow;
|
||||
c := clipsheet.ActiveCellCol;
|
||||
end else
|
||||
begin
|
||||
r := sel.Row2;
|
||||
c := sel.Col2;
|
||||
end;
|
||||
ActiveWorksheet.SelectCell(r + dr, c + dc);
|
||||
end;
|
||||
ActiveWorksheet.SetSelection(selArray);
|
||||
// Select active cell. If not found in the file, let's use the last cell of the selections
|
||||
if (clipsheet.ActiveCellRow <> 0) and (clipsheet.ActiveCellCol <> 0) then
|
||||
begin
|
||||
r := clipsheet.ActiveCellRow;
|
||||
c := clipsheet.ActiveCellCol;
|
||||
end else
|
||||
begin
|
||||
r := sel.Row2;
|
||||
c := sel.Col2;
|
||||
end;
|
||||
ActiveWorksheet.SelectCell(r + dr, c + dc);
|
||||
finally
|
||||
clipbook.Free;
|
||||
end;
|
||||
|
@ -237,7 +237,7 @@ begin
|
||||
end else
|
||||
if cell^.ContentType = cctUTF8String then begin
|
||||
FCurItem.X := AIndex;
|
||||
FCurItem.Text := FDataWorksheet.ReadAsUTF8Text(cell);
|
||||
FCurItem.Text := FDataWorksheet.ReadAsText(cell);
|
||||
end else
|
||||
begin
|
||||
FCurItem.X := FDataWorksheet.ReadAsNumber(cell);
|
||||
@ -473,7 +473,7 @@ begin
|
||||
end else
|
||||
if cell^.ContentType = cctUTF8String then begin
|
||||
ANumber := APointIndex;
|
||||
AText := FWorksheets[rngX].ReadAsUTF8Text(cell);
|
||||
AText := FWorksheets[rngX].ReadAsText(cell);
|
||||
end else
|
||||
begin
|
||||
ANumber := FWorksheets[rngX].ReadAsNumber(cell);
|
||||
|
@ -270,6 +270,7 @@ type
|
||||
|
||||
|
||||
{ TsCellFormatItem }
|
||||
|
||||
TsCellFormatItem = (cfiFontName, cfiFontSize, cfiFontColor, cfiBackgroundColor,
|
||||
cfiBorderColor);
|
||||
|
||||
@ -498,6 +499,7 @@ function SpreadsheetFormatInClipboard: Boolean;
|
||||
begin
|
||||
Result := Clipboard.HasFormat(cfBiff8Format) or
|
||||
Clipboard.HasFormat(cfBiff5Format) or
|
||||
Clipboard.HasFormat(cfOpenDocumentFormat) or
|
||||
Clipboard.HasFormat(cfHTMLFormat) or
|
||||
Clipboard.HasFormat(cfTextHTMLFormat) or
|
||||
Clipboard.HasFormat(cfCSVFormat) or
|
||||
@ -955,23 +957,12 @@ var
|
||||
I: IsSpreadsheetControl;
|
||||
C: TComponent;
|
||||
begin
|
||||
{
|
||||
// Select worksheet in tab control first
|
||||
if lniWorksheet in AChangedItems then
|
||||
for j:=0 to FListeners.Count-1 do begin
|
||||
C := TComponent(FListeners[j]);
|
||||
if C is TsWorkbookTabControl then begin
|
||||
C.GetInterface(GUID_SpreadsheetControl, I);
|
||||
I.ListenerNotification(AChangedItems, AData);
|
||||
end;
|
||||
end;
|
||||
}
|
||||
for j:=0 to FListeners.Count-1 do begin
|
||||
C := TComponent(FListeners[j]);
|
||||
if C.GetInterface(GUID_SpreadsheetControl, I) then
|
||||
I.ListenerNotification(AChangedItems, AData)
|
||||
else
|
||||
raise Exception.CreateFmt('Class %s is not prepared to be a spreadsheet listener.',
|
||||
raise Exception.CreateFmt('[TsWorkbookSource.NotifyListeners] Class %s is not prepared to be a spreadsheet listener.',
|
||||
[C.ClassName]);
|
||||
end;
|
||||
end;
|
||||
@ -1258,40 +1249,37 @@ var
|
||||
cf: Integer;
|
||||
fmt: TsSpreadsheetFormat;
|
||||
stream: TStream;
|
||||
s: String;
|
||||
begin
|
||||
Clipboard.Open;
|
||||
stream := TMemoryStream.Create;
|
||||
try
|
||||
stream := TMemoryStream.Create;
|
||||
try
|
||||
// Check whether the clipboard content is suitable for fpspreadsheet
|
||||
if Clipboard.GetFormat(cfOpenDocumentFormat, stream) then
|
||||
fmt := sfOpenDocument
|
||||
else if Clipboard.GetFormat(cfBiff8Format, stream) then
|
||||
fmt := sfExcel8
|
||||
else if Clipboard.GetFormat(cfBiff5Format, stream) then
|
||||
fmt := sfExcel5
|
||||
else if Clipboard.GetFormat(cfHTMLFormat, stream) or Clipboard.GetFormat(cfTextHTMLFormat, stream) then
|
||||
fmt := sfHTML
|
||||
else if Clipboard.GetFormat(cfCSVFormat, stream) then //or Clipboard.GetFormat(CF_TEXT, stream) then
|
||||
fmt := sfCSV
|
||||
else if Clipboard.GetFormat(PredefinedClipboardFormat(pcfText), stream) then
|
||||
fmt := sfCSV
|
||||
else begin
|
||||
// Exit if there are no spreadsheet data in clipboard
|
||||
MessageDlg('No appropriate spreadsheet data in clipboard', mtError, [mbOk], 0);
|
||||
exit;
|
||||
end;
|
||||
|
||||
// Paste stream into workbook
|
||||
FWorkbook.PasteFromClipboardStream(stream, fmt, AItem);
|
||||
|
||||
// To do: XML format
|
||||
// I don't know which format is written by xlsx and ods natively.
|
||||
finally
|
||||
stream.Free;
|
||||
// Check whether the clipboard content is suitable for fpspreadsheet
|
||||
if Clipboard.GetFormat(cfOpenDocumentFormat, stream) then
|
||||
fmt := sfOpenDocument
|
||||
else if Clipboard.GetFormat(cfBiff8Format, stream) then
|
||||
fmt := sfExcel8
|
||||
else if Clipboard.GetFormat(cfBiff5Format, stream) then
|
||||
fmt := sfExcel5
|
||||
else if Clipboard.GetFormat(cfHTMLFormat, stream) or Clipboard.GetFormat(cfTextHTMLFormat, stream) then
|
||||
fmt := sfHTML
|
||||
else if Clipboard.GetFormat(cfCSVFormat, stream) then
|
||||
fmt := sfCSV
|
||||
else if Clipboard.GetFormat(CF_TEXT, stream) then
|
||||
fmt := sfCSV
|
||||
else begin
|
||||
// Exit if there are no spreadsheet data in clipboard
|
||||
MessageDlg('No appropriate spreadsheet data in clipboard', mtError, [mbOk], 0);
|
||||
exit;
|
||||
end;
|
||||
|
||||
// Paste stream into workbook
|
||||
stream.Position := 0;
|
||||
FWorkbook.PasteFromClipboardStream(stream, fmt, AItem);
|
||||
|
||||
// To do: XML format
|
||||
// I don't know which format is written by xlsx and ods natively.
|
||||
finally
|
||||
Clipboard.Close;
|
||||
stream.Free;
|
||||
end;
|
||||
|
||||
(*
|
||||
|
@ -151,6 +151,9 @@ type
|
||||
procedure CreateNewWorkbook;
|
||||
procedure DblClick; override;
|
||||
procedure DefineProperties(Filer: TFiler); override;
|
||||
procedure DoCopyToClipboard; override;
|
||||
procedure DoCutToClipboard; override;
|
||||
procedure DoPasteFromClipboard; override;
|
||||
procedure DoOnResize; override;
|
||||
procedure DoPrepareCanvas(ACol, ARow: Integer; AState: TGridDrawState); override;
|
||||
procedure DrawAllRows; override;
|
||||
@ -1329,6 +1332,21 @@ begin
|
||||
Unused(Filer);
|
||||
end;
|
||||
|
||||
procedure TsCustomWorksheetGrid.DoCopyToClipboard;
|
||||
begin
|
||||
WorkbookSource.CopyCellsToClipboard;
|
||||
end;
|
||||
|
||||
procedure TsCustomWorksheetGrid.DoCutToClipboard;
|
||||
begin
|
||||
WorkbookSource.CutCellsToClipboard;
|
||||
end;
|
||||
|
||||
procedure TsCustomWorksheetGrid.DoPasteFromClipboard;
|
||||
begin
|
||||
WorkbookSource.PasteCellsFromClipboard(coCopyCell);
|
||||
end;
|
||||
|
||||
procedure TsCustomWorksheetGrid.DoOnResize;
|
||||
begin
|
||||
if (csDesigning in ComponentState) and (Worksheet = nil) then
|
||||
@ -3989,7 +4007,7 @@ var
|
||||
nfs: String;
|
||||
isGeneralFmt: Boolean;
|
||||
begin
|
||||
Result := Worksheet.ReadAsUTF8Text(ACell);
|
||||
Result := Worksheet.ReadAsText(ACell);
|
||||
if (Result = '') or ((ACell <> nil) and (ACell^.ContentType = cctUTF8String))
|
||||
then
|
||||
exit;
|
||||
|
Reference in New Issue
Block a user