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:
wp_xxyyzz
2015-09-28 20:23:28 +00:00
parent 295db4cdda
commit 95704110ce
7 changed files with 157 additions and 98 deletions

View File

@@ -348,6 +348,7 @@ type
procedure AcShowGridLinesExecute(Sender: TObject); procedure AcShowGridLinesExecute(Sender: TObject);
procedure AcShowGridLinesUpdate(Sender: TObject); procedure AcShowGridLinesUpdate(Sender: TObject);
procedure AcViewInspectorExecute(Sender: TObject); procedure AcViewInspectorExecute(Sender: TObject);
procedure EditCut1Execute(Sender: TObject);
procedure HyperlinkHandler(Sender: TObject; ACaption: String; procedure HyperlinkHandler(Sender: TObject; ACaption: String;
var AHyperlink: TsHyperlink); var AHyperlink: TsHyperlink);
procedure InspectorTabControlChange(Sender: TObject); 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 InspectorSplitter.Left := 0; // Make sure that the splitter is always at the left of the inspector
end; end;
procedure TMainForm.EditCut1Execute(Sender: TObject);
begin
//
end;
{ Event handler for hyperlinks: it only has to provide the hyperlink data { Event handler for hyperlinks: it only has to provide the hyperlink data
which are applied to the active cell by the TsCellHyperlinkAction. which are applied to the active cell by the TsCellHyperlinkAction.
Is called by the "new hyperlink" and "edit hyperlink" actions. Is called by the "new hyperlink" and "edit hyperlink" actions.

View File

@@ -118,6 +118,7 @@ type
FCopyMode: TsCopyMode; FCopyMode: TsCopyMode;
public public
procedure ExecuteTarget(Target: TObject); override; procedure ExecuteTarget(Target: TObject); override;
function HandlesTarget(Target: TObject): Boolean; override;
procedure UpdateTarget(Target: TObject); override; procedure UpdateTarget(Target: TObject); override;
published published
property Caption; property Caption;
@@ -525,7 +526,7 @@ implementation
uses uses
StdCtrls, ExtCtrls, Buttons, Forms, StdCtrls, ExtCtrls, Buttons, Forms,
fpsUtils, fpsNumFormat, fpsVisualUtils; fpsUtils, fpsNumFormat, fpsVisualUtils, fpSpreadsheetGrid;
procedure Register; procedure Register;
begin begin
@@ -767,7 +768,7 @@ const
coCopyFormat, coCopyValue, coCopyFormula, coCopyCell coCopyFormat, coCopyValue, coCopyFormula, coCopyCell
); );
begin begin
Unused(Target); if Target is TsCustomWorksheetGrid then
case FCopyMode of case FCopyMode of
cmBrush: cmBrush:
begin begin
@@ -789,6 +790,25 @@ begin
Checked := false; Checked := false;
WorkbookSource.PasteCellsFromClipboard(OPERATIONS[FCopyItem]); WorkbookSource.PasteCellsFromClipboard(OPERATIONS[FCopyItem]);
end; 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: Result := inherited HandlesTarget(Target);
cmCopy,
cmCut,
cmPaste: Result := (Target <> nil) and
( (Target is TsCustomWorksheetGrid) or (Target is TCustomEdit) );
end; end;
end; end;

View File

@@ -22,6 +22,7 @@ type
procedure ReadNumber(AStream: TStream); override; procedure ReadNumber(AStream: TStream); override;
public public
constructor Create(AWorkbook: TsWorkbook); override; constructor Create(AWorkbook: TsWorkbook); override;
procedure ReadFromClipboardStream(AStream: TStream); override;
procedure ReadFromFile(AFileName: String); override; procedure ReadFromFile(AFileName: String); override;
procedure ReadFromStream(AStream: TStream); override; procedure ReadFromStream(AStream: TStream); override;
procedure ReadFromStrings(AStrings: TStrings); override; procedure ReadFromStrings(AStrings: TStrings); override;
@@ -200,6 +201,11 @@ begin
Unused(AStream); Unused(AStream);
end; end;
procedure TsCSVReader.ReadFromClipboardStream(AStream: TStream);
begin
ReadFromStream(AStream);
end;
procedure TsCSVReader.ReadFromFile(AFileName: String); procedure TsCSVReader.ReadFromFile(AFileName: String);
begin begin
FWorksheetName := ChangeFileExt(ExtractFileName(AFileName), ''); FWorksheetName := ChangeFileExt(ExtractFileName(AFileName), '');
@@ -372,9 +378,10 @@ end;
procedure TsCSVWriter.WriteSheet(AStream: TStream; AWorksheet: TsWorksheet); procedure TsCSVWriter.WriteSheet(AStream: TStream; AWorksheet: TsWorksheet);
var var
r: Cardinal; r: Cardinal;
FirstRow: Cardinal; firstRow: Cardinal;
LastRow: Cardinal; lastRow: Cardinal;
cell: PCell; cell: PCell;
n: Integer;
begin begin
FWorksheet := AWorksheet; FWorksheet := AWorksheet;
@@ -385,16 +392,24 @@ begin
FCSVBuilder.QuoteChar := CSVParams.QuoteChar; FCSVBuilder.QuoteChar := CSVParams.QuoteChar;
FCSVBuilder.SetOutput(AStream); FCSVBuilder.SetOutput(AStream);
n := FWorksheet.GetCellCount;
if FClipboardMode and (n = 1) then
begin
cell := FWorksheet.Cells.GetFirstCell;
WriteCellToStream(AStream, cell);
end else
begin
if FClipboardMode then if FClipboardMode then
FirstRow := FWorksheet.GetFirstRowIndex else firstRow := FWorksheet.GetFirstRowIndex else
FirstRow := 0; firstRow := 0;
LastRow := FWorksheet.GetLastOccupiedRowIndex; lastRow := FWorksheet.GetLastOccupiedRowIndex;
for r := FirstRow to LastRow do for r := firstRow to lastRow do
begin begin
for cell in FWorksheet.Cells.GetRowEnumerator(r) do for cell in FWorksheet.Cells.GetRowEnumerator(r) do
WriteCellToStream(AStream, cell); WriteCellToStream(AStream, cell);
FCSVBuilder.AppendRow; FCSVBuilder.AppendRow;
end; end;
end;
finally finally
FreeAndNil(FCSVBuilder); FreeAndNil(FCSVBuilder);
end; end;
@@ -433,7 +448,7 @@ end;
initialization initialization
InitFormatSettings(CSVParams.FormatSettings); InitFormatSettings(CSVParams.FormatSettings);
RegisterSpreadFormat(TsCSVReader, TsCSVWriter, sfCSV, false, true); RegisterSpreadFormat(TsCSVReader, TsCSVWriter, sfCSV, true, true);
end. end.

View File

@@ -1601,6 +1601,10 @@ begin
toRow := AToCell^.Row; toRow := AToCell^.Row;
toCol := AToCell^.Col; toCol := AToCell^.Col;
// Avoid misplaced notifications during the copy operations when things could
// not yet be in place.
FWorkbook.DisableNotifications;
// Copy cell values // Copy cell values
AToCell^ := AFromCell^; AToCell^ := AFromCell^;
@@ -1648,6 +1652,11 @@ begin
end; end;
end; end;
FWorkbook.EnableNotifications;
// Notify visual controls of changes
ChangedCell(AToCell^.Row, AToCell^.Col);
// Notify visual controls of possibly changed row heights. // Notify visual controls of possibly changed row heights.
ChangedFont(AToCell^.Row, AToCell^.Col); ChangedFont(AToCell^.Row, AToCell^.Col);
end; end;
@@ -7876,6 +7885,8 @@ begin
end; end;
// Select the same cells as in the clipboard // Select the same cells as in the clipboard
n := clipsheet.GetSelectionCount; n := clipsheet.GetSelectionCount;
if n > 0 then
begin
SetLength(selArray, n); SetLength(selArray, n);
for i := 0 to n-1 do for i := 0 to n-1 do
begin begin
@@ -7897,6 +7908,7 @@ begin
c := sel.Col2; c := sel.Col2;
end; end;
ActiveWorksheet.SelectCell(r + dr, c + dc); ActiveWorksheet.SelectCell(r + dr, c + dc);
end;
finally finally
clipbook.Free; clipbook.Free;
end; end;

View File

@@ -237,7 +237,7 @@ begin
end else end else
if cell^.ContentType = cctUTF8String then begin if cell^.ContentType = cctUTF8String then begin
FCurItem.X := AIndex; FCurItem.X := AIndex;
FCurItem.Text := FDataWorksheet.ReadAsUTF8Text(cell); FCurItem.Text := FDataWorksheet.ReadAsText(cell);
end else end else
begin begin
FCurItem.X := FDataWorksheet.ReadAsNumber(cell); FCurItem.X := FDataWorksheet.ReadAsNumber(cell);
@@ -473,7 +473,7 @@ begin
end else end else
if cell^.ContentType = cctUTF8String then begin if cell^.ContentType = cctUTF8String then begin
ANumber := APointIndex; ANumber := APointIndex;
AText := FWorksheets[rngX].ReadAsUTF8Text(cell); AText := FWorksheets[rngX].ReadAsText(cell);
end else end else
begin begin
ANumber := FWorksheets[rngX].ReadAsNumber(cell); ANumber := FWorksheets[rngX].ReadAsNumber(cell);

View File

@@ -270,6 +270,7 @@ type
{ TsCellFormatItem } { TsCellFormatItem }
TsCellFormatItem = (cfiFontName, cfiFontSize, cfiFontColor, cfiBackgroundColor, TsCellFormatItem = (cfiFontName, cfiFontSize, cfiFontColor, cfiBackgroundColor,
cfiBorderColor); cfiBorderColor);
@@ -498,6 +499,7 @@ function SpreadsheetFormatInClipboard: Boolean;
begin begin
Result := Clipboard.HasFormat(cfBiff8Format) or Result := Clipboard.HasFormat(cfBiff8Format) or
Clipboard.HasFormat(cfBiff5Format) or Clipboard.HasFormat(cfBiff5Format) or
Clipboard.HasFormat(cfOpenDocumentFormat) or
Clipboard.HasFormat(cfHTMLFormat) or Clipboard.HasFormat(cfHTMLFormat) or
Clipboard.HasFormat(cfTextHTMLFormat) or Clipboard.HasFormat(cfTextHTMLFormat) or
Clipboard.HasFormat(cfCSVFormat) or Clipboard.HasFormat(cfCSVFormat) or
@@ -955,23 +957,12 @@ var
I: IsSpreadsheetControl; I: IsSpreadsheetControl;
C: TComponent; C: TComponent;
begin 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 for j:=0 to FListeners.Count-1 do begin
C := TComponent(FListeners[j]); C := TComponent(FListeners[j]);
if C.GetInterface(GUID_SpreadsheetControl, I) then if C.GetInterface(GUID_SpreadsheetControl, I) then
I.ListenerNotification(AChangedItems, AData) I.ListenerNotification(AChangedItems, AData)
else 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]); [C.ClassName]);
end; end;
end; end;
@@ -1258,9 +1249,8 @@ var
cf: Integer; cf: Integer;
fmt: TsSpreadsheetFormat; fmt: TsSpreadsheetFormat;
stream: TStream; stream: TStream;
s: String;
begin begin
Clipboard.Open;
try
stream := TMemoryStream.Create; stream := TMemoryStream.Create;
try try
// Check whether the clipboard content is suitable for fpspreadsheet // Check whether the clipboard content is suitable for fpspreadsheet
@@ -1272,9 +1262,9 @@ begin
fmt := sfExcel5 fmt := sfExcel5
else if Clipboard.GetFormat(cfHTMLFormat, stream) or Clipboard.GetFormat(cfTextHTMLFormat, stream) then else if Clipboard.GetFormat(cfHTMLFormat, stream) or Clipboard.GetFormat(cfTextHTMLFormat, stream) then
fmt := sfHTML fmt := sfHTML
else if Clipboard.GetFormat(cfCSVFormat, stream) then //or Clipboard.GetFormat(CF_TEXT, stream) then else if Clipboard.GetFormat(cfCSVFormat, stream) then
fmt := sfCSV fmt := sfCSV
else if Clipboard.GetFormat(PredefinedClipboardFormat(pcfText), stream) then else if Clipboard.GetFormat(CF_TEXT, stream) then
fmt := sfCSV fmt := sfCSV
else begin else begin
// Exit if there are no spreadsheet data in clipboard // Exit if there are no spreadsheet data in clipboard
@@ -1283,6 +1273,7 @@ begin
end; end;
// Paste stream into workbook // Paste stream into workbook
stream.Position := 0;
FWorkbook.PasteFromClipboardStream(stream, fmt, AItem); FWorkbook.PasteFromClipboardStream(stream, fmt, AItem);
// To do: XML format // To do: XML format
@@ -1290,9 +1281,6 @@ begin
finally finally
stream.Free; stream.Free;
end; end;
finally
Clipboard.Close;
end;
(* (*
exit; exit;

View File

@@ -151,6 +151,9 @@ type
procedure CreateNewWorkbook; procedure CreateNewWorkbook;
procedure DblClick; override; procedure DblClick; override;
procedure DefineProperties(Filer: TFiler); override; procedure DefineProperties(Filer: TFiler); override;
procedure DoCopyToClipboard; override;
procedure DoCutToClipboard; override;
procedure DoPasteFromClipboard; override;
procedure DoOnResize; override; procedure DoOnResize; override;
procedure DoPrepareCanvas(ACol, ARow: Integer; AState: TGridDrawState); override; procedure DoPrepareCanvas(ACol, ARow: Integer; AState: TGridDrawState); override;
procedure DrawAllRows; override; procedure DrawAllRows; override;
@@ -1329,6 +1332,21 @@ begin
Unused(Filer); Unused(Filer);
end; 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; procedure TsCustomWorksheetGrid.DoOnResize;
begin begin
if (csDesigning in ComponentState) and (Worksheet = nil) then if (csDesigning in ComponentState) and (Worksheet = nil) then
@@ -3989,7 +4007,7 @@ var
nfs: String; nfs: String;
isGeneralFmt: Boolean; isGeneralFmt: Boolean;
begin begin
Result := Worksheet.ReadAsUTF8Text(ACell); Result := Worksheet.ReadAsText(ACell);
if (Result = '') or ((ACell <> nil) and (ACell^.ContentType = cctUTF8String)) if (Result = '') or ((ACell <> nil) and (ACell^.ContentType = cctUTF8String))
then then
exit; exit;