fpspreadsheet: More combinations of source and destination cells for copy/paste to clipboard.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@4477 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2016-01-26 23:37:08 +00:00
parent 07e26c4abe
commit 590c9d8a47
3 changed files with 119 additions and 84 deletions

View File

@ -748,27 +748,7 @@ type
procedure PasteFromClipboardStream(AStream: TStream; AFormat: TsSpreadsheetFormat;
AOperation: TsCopyOperation; AParams: TsStreamParams = [];
ATransposed: Boolean = false);
(*
{ Color handling }
function FPSColorToHexString(AColor: TsColor; ARGBColor: TFPColor): String;
function GetColorName(AColorIndex: TsColor): string; overload;
procedure GetColorName(AColorValue: TsColorValue; out AName: String); overload;
function GetPaletteColor(AColorIndex: TsColor): TsColorValue;
function GetPaletteColorAsHTMLStr(AColorIndex: TsColor): String;
procedure SetPaletteColor(AColorIndex: TsColor; AColorValue: TsColorValue);
function GetPaletteSize: Integer;
procedure UseDefaultPalette;
procedure UsePalette(APalette: PsPalette; APaletteCount: Word;
ABigEndian: Boolean = false);
function UsesColor(AColorIndex: TsColor): Boolean;
*)
(*
{ Searching }
function SearchFirst(ASearchText: String; AParams: TsSearchParams;
out AWorksheet: TsWorksheet; out ARow, ACol: Cardinal): Boolean;
function SearchNext(out AWorksheet: TsWorksheet;
out ARow, ACol: Cardinal): Boolean;
*)
{ Utilities }
procedure DisableNotifications;
procedure EnableNotifications;
@ -1654,18 +1634,18 @@ begin
CopyFormat(AFromCell, AToCell);
// Merged?
if IsMergeBase(AFromCell) then
if srcSheet.IsMergeBase(AFromCell) then
begin
FindMergedRange(AFromCell, row1, col1, row2, col2);
srcSheet.FindMergedRange(AFromCell, row1, col1, row2, col2);
MergeCells(toRow, toCol, toRow + LongInt(row2) - LongInt(row1), toCol + LongInt(col2) - LongInt(col1));
end;
// Copy comment
if HasComment(AFromCell) then
if srcSheet.HasComment(AFromCell) then
WriteComment(AToCell, ReadComment(AFromCell));
// Copy hyperlink
hyperlink := FindHyperlink(AFromCell);
hyperlink := srcSheet.FindHyperlink(AFromCell);
if hyperlink <> nil then
WriteHyperlink(AToCell, hyperlink^.Target, hyperlink^.Tooltip);
@ -6515,37 +6495,6 @@ begin
Unused(arg);
TsWorksheet(data).Free;
end;
(*
{@@ ----------------------------------------------------------------------------
Searches the first cell matching the ASearchText according to the
specified AParams.
Use SearchNext for subsequent calls for the next occurances.
The function result is TRUE if the search text has been found. In this case
AWorksheet, ARow and ACol specify the cell containing the search text.
-------------------------------------------------------------------------------}
function TsWorkbook.SearchFirst(ASearchText: String; AParams: TsSearchParams;
out AWorksheet: TsWorksheet; out ARow, ACol: Cardinal): Boolean;
begin
FreeAndNil(FSearchEngine);
FSearchEngine := TsSearchEngine.Create(self);
with (FSearchEngine as TsSearchEngine) do
Result := FindFirst(ASearchText, AParams, AWorksheet, ARow, ACol);
end;
{@@ ----------------------------------------------------------------------------
Searches the next cell matching the text and params specified a the preceding
call to SearchFirst.
The function result is TRUE if the search text has been found. In this case
AWorksheet, ARow and ACol specify the cell containing the search text.
-------------------------------------------------------------------------------}
function TsWorkbook.SearchNext(out AWorksheet: TsWorksheet;
out ARow, ACol: Cardinal): Boolean;
begin
if FSearchEngine = nil then
Result := false else
Result := (FSearchEngine as TsSearchEngine).FindNext(AWorksheet, ARow, ACol);
end;
*)
{@@ ----------------------------------------------------------------------------
Helper method to disable notification of visual controls
@ -7931,6 +7880,8 @@ begin
for c := sel.Col1 to sel.Col2 do
begin
srccell := ActiveWorksheet.FindCell(r, c);
if ActiveWorksheet.IsMerged(srccell) then
srccell := ActiveWorksheet.FindMergeBase(srccell);
if srccell <> nil then begin
destcell := clipsheet.AddCell(r, c);
clipsheet.CopyCell(srccell, destcell);
@ -7970,7 +7921,10 @@ var
r, c: LongInt;
dr, dc: LongInt;
srcCell, destCell: PCell;
i, n: Integer;
i: Integer; // counter
ncs, nrs, ncd, nrd: Integer; // Num cols source, num rows source, ...
rdest, cdest: Integer; // row and column index at destination
nselS, nselD: Integer; // count of selected blocks
begin
if AStream = nil then
exit;
@ -7990,29 +7944,40 @@ begin
// treatment for clipboard, if needed.
clipbook.ReadFromStream(AStream, AFormat, AParams + [spClipboard]);
clipsheet := clipbook.GetWorksheetByIndex(0);
// Find offset of active cell to left/top cell in temporary sheet
dr := LongInt(ActiveWorksheet.ActiveCellRow) - clipsheet.GetFirstRowIndex(true);
dc := LongInt(ActiveWorksheet.ActiveCellCol) - clipsheet.GetFirstColIndex(true);
// Copy cells from temporary workbook to active worksheet.
// Shift them such that the top/left cell of temp sheet is at the active cell.
for srcCell in clipsheet.Cells do
begin
r := LongInt(srcCell.Row) + dr;
c := LongInt(srcCell.Col) + dc;
destCell := ActiveWorksheet.GetCell(r, c);
case AOperation of
coCopyCell : ActiveWorksheet.CopyCell(srcCell, destCell);
coCopyValue : ActiveWorksheet.CopyValue(srcCell, destCell);
coCopyFormat : ActiveWorksheet.CopyFormat(srcCell, destCell);
coCopyFormula : ActiveWorksheet.CopyFormula(srcCell, destCell);
end;
end;
// Select the same cells as in the clipboard
n := clipsheet.GetSelectionCount;
if n > 0 then
// count of blocks in source (clipboard sheet)
nselS := clipsheet.GetSelectionCount;
// count of selected blocks at destination
nselD := ActiveWorksheet.GetSelectionCount;
// -------------------------------------------------------------------------
// Case (1): Destination is a single cell, source can be any shape
// --> Source shape is duplicated starting at destination
// -------------------------------------------------------------------------
if (nselD = 1)
and (ActiveWorksheet.GetSelection[0].Col1 = ActiveWorksheet.GetSelection[0].Col2)
and (ActiveWorksheet.GetSelection[0].Row1 = ActiveWorksheet.GetSelection[0].Row2)
then begin
// Find offset of active cell to left/top cell in clipboard sheet
dr := LongInt(ActiveWorksheet.ActiveCellRow) - clipsheet.GetFirstRowIndex(true);
dc := LongInt(ActiveWorksheet.ActiveCellCol) - clipsheet.GetFirstColIndex(true);
// Copy cells from clipboard sheet to active worksheet
// Shift them such that top/left of clipboard sheet is at active cell
for srcCell in clipsheet.Cells do
begin
SetLength(selArray, n);
for i := 0 to n-1 do
r := LongInt(srcCell^.Row) + dr;
c := LongInt(srcCell^.Col) + dc;
destcell := ActiveWorksheet.GetCell(r, c);
case AOperation of
coCopyCell : ActiveWorksheet.CopyCell(srcCell, destCell);
coCopyValue : ActiveWorksheet.CopyValue(srcCell, destCell);
coCopyFormat : ActiveWorksheet.CopyFormat(srcCell, destCell);
coCopyFormula : ActiveWorksheet.CopyFormula(srcCell, destCell);
end;
end;
// Select all copied cells
SetLength(selArray, nselS);
for i := 0 to nselS-1 do
begin
sel := clipsheet.GetSelection[i];
selArray[i].Row1 := LongInt(sel.Row1) + dr;
@ -8032,7 +7997,67 @@ begin
c := sel.Col2;
end;
ActiveWorksheet.SelectCell(r + dr, c + dc);
end;
end
else
// -------------------------------------------------------------------------
// Case (2): Source is a single block (not necessarily a cell), Dest can be
// any shape --> source is tiled into destination
// -------------------------------------------------------------------------
if nselS = 1 then
begin
// size of source block
with clipsheet do
begin
ncs := LongInt(GetLastColIndex(true)) - LongInt(GetFirstColIndex(true)) + 1;
nrs := LongInt(GetLastRowIndex(true)) - LongInt(GetFirstRowIndex(true)) + 1;
end;
// Iterate over all destination blocks
for i := 0 to nselD-1 do
begin
// size of current selected block at destination
with ActiveWorksheet.GetSelection[i] do
begin
ncd := LongInt(Col2) - LongInt(Col1) + 1;
nrd := LongInt(Row2) - LongInt(Row1) + 1;
end;
r := ActiveWorksheet.GetSelection[i].Row1;
while r <= ActiveWorksheet.GetSelection[i].Row2 do begin
c := ActiveWorksheet.GetSelection[i].Col1;
while c <= ActiveWorksheet.GetSelection[i].Col2 do begin
dr := r - clipsheet.GetFirstRowIndex;
dc := c - clipsheet.GetFirstColIndex;
for srccell in clipsheet.Cells do
begin
rdest := srccell^.Row + dr;
if rdest > ActiveWorksheet.GetSelection[i].Row2 then
Continue;
cdest := srcCell^.Col + dc;
if cdest > ActiveWorksheet.GetSelection[i].Col2 then
Continue;
destcell := ActiveWorksheet.GetCell(
LongInt(srcCell^.Row) + dr,
LongInt(srcCell^.Col) + dc
);
case AOperation of
coCopyCell : ActiveWorksheet.CopyCell(srcCell, destCell);
coCopyValue : ActiveWorksheet.CopyValue(srcCell, destCell);
coCopyFormat : ActiveWorksheet.CopyFormat(srcCell, destCell);
coCopyFormula : ActiveWorksheet.CopyFormula(srcCell, destCell);
end;
end; // for srcCell
inc(c, ncs);
end; // while c...
inc(r, nrs);
end; // while r...
end; // for i
// No need to select copied cells - they already are.
end
else
// -------------------------------------------------------------------------
// Other arrangements of source and destination are not supported
// -------------------------------------------------------------------------
raise Exception.Create('This arrangement of source and destination '+
'cells in not supported for copy & paste');
finally
clipbook.Free;
end;

View File

@ -1526,14 +1526,16 @@ end;
procedure TsCustomWorksheetGrid.DoCutToClipboard;
begin
// This next comment does not seem to be valid any more: Issue handled by eating key in KeyDown
// Remove for the moment: If TsCopyActions is available this code would be executed twice (and destroy the clipboard)
//WorkbookSource.CutCellsToClipboard;
WorkbookSource.CutCellsToClipboard;
end;
procedure TsCustomWorksheetGrid.DoPasteFromClipboard;
begin
// This next comment does not seem to be valid any more: Issue handled by eating key in KeyDown
// Remove for the moment: If TsPasteActions is available this code would be executed twice
//WorkbookSource.PasteCellsFromClipboard(coCopyCell);
WorkbookSource.PasteCellsFromClipboard(coCopyCell);
end;
{ Make the cell editor the same size as the edited cell, in particular for
@ -2347,6 +2349,7 @@ var
cell: PCell;
r1,c1,r2,c2: Cardinal;
delta: Integer;
savedPenMode: TPenMode;
begin
if Worksheet = nil then
exit;
@ -2382,6 +2385,7 @@ begin
end; }
// Set up the canvas
savedPenMode := Canvas.Pen.Mode;
Canvas.Pen.Assign(FSelPen);
if UseXORFeatures then begin
Canvas.Pen.Color := clWhite;
@ -2391,6 +2395,8 @@ begin
// Paint
Canvas.Rectangle(R);
Canvas.Pen.Mode := savedPenMode;
end;
{@@ ----------------------------------------------------------------------------
@ -3830,6 +3836,10 @@ begin
end;
inherited;
case Key of
VK_C, VK_X, VK_V: Key := 0; // Clipboard has already been handled, avoid passing key to CellAction
end;
end;
{@@ ----------------------------------------------------------------------------

View File

@ -2238,7 +2238,7 @@ begin
(AFont.Color = AColor) and
(AFont.Position = APos);
end;
(*
{@@ ----------------------------------------------------------------------------
Constructs a string of length "Len" containing random uppercase characters
-------------------------------------------------------------------------------}
@ -2248,7 +2248,7 @@ begin
While Length(Result) < Len do
Result := Result + char(ord('A') + random(26));
end;
(*
{@@ ----------------------------------------------------------------------------
Constructs a unique folder name in the temp directory of the OS
-------------------------------------------------------------------------------}