You've already forked lazarus-ccr
fpspreadsheet: Fix grid's Col/RowCount not being reduced if a sheet with less cols/rows than the current sheet is selected (http://forum.lazarus.freepascal.org/index.php/topic,35182.msg232477.html#msg232477). Introduce top/left cell indexes in worksheet to make sure that active cell remains at the row/col stored in the worksheet when changing worksheets.
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@5560 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -84,6 +84,8 @@ type
|
|||||||
FRows, FCols: TIndexedAVLTree; // This lists contain only rows or cols with styles different from default
|
FRows, FCols: TIndexedAVLTree; // This lists contain only rows or cols with styles different from default
|
||||||
FActiveCellRow: Cardinal;
|
FActiveCellRow: Cardinal;
|
||||||
FActiveCellCol: Cardinal;
|
FActiveCellCol: Cardinal;
|
||||||
|
FTopRow: Cardinal;
|
||||||
|
FLeftCol: Cardinal;
|
||||||
FSelection: TsCellRangeArray;
|
FSelection: TsCellRangeArray;
|
||||||
FLeftPaneWidth: Integer;
|
FLeftPaneWidth: Integer;
|
||||||
FTopPaneHeight: Integer;
|
FTopPaneHeight: Integer;
|
||||||
@ -477,6 +479,8 @@ type
|
|||||||
function GetSelectionRangeIndexOfActiveCell: Integer;
|
function GetSelectionRangeIndexOfActiveCell: Integer;
|
||||||
procedure SetSelection(const ASelection: TsCellRangeArray);
|
procedure SetSelection(const ASelection: TsCellRangeArray);
|
||||||
|
|
||||||
|
procedure ScrollTo(ANewTopRow, ANewLeftCol: Cardinal);
|
||||||
|
|
||||||
// Comments
|
// Comments
|
||||||
function FindComment(ACell: PCell): PsComment;
|
function FindComment(ACell: PCell): PsComment;
|
||||||
function HasComment(ACell: PCell): Boolean;
|
function HasComment(ACell: PCell): Boolean;
|
||||||
@ -582,6 +586,10 @@ type
|
|||||||
property ActiveCellCol: Cardinal read FActiveCellCol;
|
property ActiveCellCol: Cardinal read FActiveCellCol;
|
||||||
{@@ Row index of the selected cell of this worksheet }
|
{@@ Row index of the selected cell of this worksheet }
|
||||||
property ActiveCellRow: Cardinal read FActiveCellRow;
|
property ActiveCellRow: Cardinal read FActiveCellRow;
|
||||||
|
{@@ Index of the left-most visible column in the grid - used by WorksheetGrid}
|
||||||
|
property LeftCol: Cardinal read FLeftCol;
|
||||||
|
{@@ Index of the top-most visible row in the grid - used by WorksheetGrid }
|
||||||
|
property TopRow: Cardinal read FTopRow;
|
||||||
{@@ Number of frozen columns which do not scroll }
|
{@@ Number of frozen columns which do not scroll }
|
||||||
property LeftPaneWidth: Integer read FLeftPaneWidth write FLeftPaneWidth;
|
property LeftPaneWidth: Integer read FLeftPaneWidth write FLeftPaneWidth;
|
||||||
{@@ Number of frozen rows which do not scroll }
|
{@@ Number of frozen rows which do not scroll }
|
||||||
@ -4225,6 +4233,17 @@ begin
|
|||||||
FSelection[i] := ASelection[i];
|
FSelection[i] := ASelection[i];
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{@@ ----------------------------------------------------------------------------
|
||||||
|
Uses the passed parameters a TopRow and LeftCol. These are used by the
|
||||||
|
TsWorksheetGrid to scroll the visible grid such that the corresponding cell
|
||||||
|
is at the top/left.
|
||||||
|
-------------------------------------------------------------------------------}
|
||||||
|
procedure TsWorksheet.ScrollTo(ANewTopRow, ANewLeftCol: Cardinal);
|
||||||
|
begin
|
||||||
|
FTopRow := ANewTopRow;
|
||||||
|
FLeftCol := ANewLeftCol;
|
||||||
|
end;
|
||||||
|
|
||||||
{@@ ----------------------------------------------------------------------------
|
{@@ ----------------------------------------------------------------------------
|
||||||
Helper method to update internal caching variables
|
Helper method to update internal caching variables
|
||||||
-------------------------------------------------------------------------------}
|
-------------------------------------------------------------------------------}
|
||||||
|
@ -1071,7 +1071,8 @@ begin
|
|||||||
AWorkbook.DisableNotifications;
|
AWorkbook.DisableNotifications;
|
||||||
|
|
||||||
if AWorkbook <> FWorkbook then
|
if AWorkbook <> FWorkbook then
|
||||||
InternalCreateNewWorkbook(AWorkbook);
|
InternalCreateNewWorkbook(AWorkbook) else
|
||||||
|
SetOptions(FOptions);
|
||||||
WorkbookOpenedHandler(self);
|
WorkbookOpenedHandler(self);
|
||||||
|
|
||||||
if AWorksheetIndex = -1 then
|
if AWorksheetIndex = -1 then
|
||||||
@ -1672,10 +1673,10 @@ begin
|
|||||||
FWorksheet.OnZoom := @WorksheetZoomHandler;
|
FWorksheet.OnZoom := @WorksheetZoomHandler;
|
||||||
NotifyListeners([lniWorksheet]);
|
NotifyListeners([lniWorksheet]);
|
||||||
FWorksheet := AWorksheet; // !!!!!
|
FWorksheet := AWorksheet; // !!!!!
|
||||||
if FWorksheet.ActiveCellRow = Cardinal(-1) then
|
if FWorksheet.ActiveCellRow = UNASSIGNED_ROW_COL_INDEX then
|
||||||
r := FWorksheet.TopPaneHeight else
|
r := FWorksheet.TopPaneHeight else
|
||||||
r := FWorksheet.ActiveCellRow;
|
r := FWorksheet.ActiveCellRow;
|
||||||
if FWorksheet.ActiveCellCol = Cardinal(-1) then
|
if FWorksheet.ActiveCellCol = UNASSIGNED_ROW_COL_INDEX then
|
||||||
c := FWorksheet.LeftPaneWidth else
|
c := FWorksheet.LeftPaneWidth else
|
||||||
c := FWorksheet.ActiveCellCol;
|
c := FWorksheet.ActiveCellCol;
|
||||||
SelectCell(r, c);
|
SelectCell(r, c);
|
||||||
|
@ -15,6 +15,8 @@ unit fpspreadsheetgrid;
|
|||||||
{$mode objfpc}{$H+}
|
{$mode objfpc}{$H+}
|
||||||
{$I ..\fps.inc}
|
{$I ..\fps.inc}
|
||||||
|
|
||||||
|
{.$DEFINE GRID_DEBUG}
|
||||||
|
|
||||||
{ To do:
|
{ To do:
|
||||||
- When Lazarus 1.4 comes out remove the workaround for the RGB2HLS bug in
|
- When Lazarus 1.4 comes out remove the workaround for the RGB2HLS bug in
|
||||||
FindNearestPaletteIndex.
|
FindNearestPaletteIndex.
|
||||||
@ -247,6 +249,7 @@ type
|
|||||||
procedure SetEditText(ACol, ARow: Longint; const AValue: string); override;
|
procedure SetEditText(ACol, ARow: Longint; const AValue: string); override;
|
||||||
procedure Setup;
|
procedure Setup;
|
||||||
procedure Sort(AColSorting: Boolean; AIndex, AIndxFrom, AIndxTo:Integer); override;
|
procedure Sort(AColSorting: Boolean; AIndex, AIndxFrom, AIndxTo:Integer); override;
|
||||||
|
procedure TopLeftChanged; override;
|
||||||
function TrimToCell(ACell: PCell): String;
|
function TrimToCell(ACell: PCell): String;
|
||||||
|
|
||||||
{@@ Automatically recalculate formulas whenever a cell value changes. }
|
{@@ Automatically recalculate formulas whenever a cell value changes. }
|
||||||
@ -4081,45 +4084,100 @@ end;
|
|||||||
procedure TsCustomWorksheetGrid.ListenerNotification(AChangedItems: TsNotificationItems;
|
procedure TsCustomWorksheetGrid.ListenerNotification(AChangedItems: TsNotificationItems;
|
||||||
AData: Pointer = nil);
|
AData: Pointer = nil);
|
||||||
var
|
var
|
||||||
|
actgrow, actgcol: Integer;
|
||||||
grow, gcol: Integer;
|
grow, gcol: Integer;
|
||||||
srow, scol: Cardinal;
|
srow, scol: Cardinal;
|
||||||
cell: PCell;
|
cell: PCell;
|
||||||
lRow: PRow;
|
lRow: PRow;
|
||||||
|
|
||||||
|
{$IFDEF GRID_DEBUG}
|
||||||
|
procedure DebugNotification(ACaption: String);
|
||||||
|
var
|
||||||
|
s: String;
|
||||||
|
begin
|
||||||
|
WriteLn(ACaption);
|
||||||
|
s := '';
|
||||||
|
if (lniWorksheet in AChangedItems) then s := s + 'lniWorksheet, ';
|
||||||
|
if (lniCell in AChangedItems) then s := s + 'lniCell, ';
|
||||||
|
if (lniSelection in AChangedItems) then s := s + 'lniSelection, ';
|
||||||
|
if (lniAbortSelection in AChangedItems) then s := s + 'lniAbortSelection, ';
|
||||||
|
if (lniRow in AChangedItems) then s := s + 'lniRow, ';
|
||||||
|
if (lniCol in AChangedItems) then s := s + 'lniCol, ';
|
||||||
|
if (lniWorksheetZoom in AChangedItems) then s := s + 'lniWorksheetZoom, ';
|
||||||
|
if s <> '' then SetLength(s, Length(s) - 2);
|
||||||
|
WriteLn(' AChangedItems = [', s, ']');
|
||||||
|
WriteLn(' ActiveCellRow: ', Worksheet.ActiveCellRow, ' ActiveCellCol: ', Worksheet.ActiveCellCol);
|
||||||
|
WriteLn(' TopRow: ', Worksheet.TopRow, ' LeftCol: ', Worksheet.LeftCol);
|
||||||
|
WriteLn;
|
||||||
|
end;
|
||||||
|
{$ENDIF}
|
||||||
|
|
||||||
begin
|
begin
|
||||||
Unused(AData);
|
Unused(AData);
|
||||||
|
|
||||||
|
{$IFDEF GRID_DEBUG}
|
||||||
|
if Worksheet <> nil then
|
||||||
|
DebugNotification('BEFORE ListenerNotification WorksheetGrid "' + Worksheet.Name + '":');
|
||||||
|
{$ENDIF}
|
||||||
|
|
||||||
// Nothing to do for "workbook changed" because this is always combined with
|
// Nothing to do for "workbook changed" because this is always combined with
|
||||||
// "worksheet changed".
|
// "worksheet changed".
|
||||||
|
|
||||||
// Worksheet changed
|
// Worksheet changed
|
||||||
if (lniWorksheet in AChangedItems) then
|
if (lniWorksheet in AChangedItems) then
|
||||||
begin
|
begin
|
||||||
if (Worksheet <> nil) then
|
BeginUpdate; // avoid flicker...
|
||||||
begin
|
try
|
||||||
inc(FLockSetup);
|
if (Worksheet <> nil) then
|
||||||
ShowHeaders := (soShowHeaders in Worksheet.Options);
|
begin
|
||||||
ShowGridLines := (soShowGridLines in Worksheet.Options);
|
// remember indexes of top/left and active cell
|
||||||
if (soHasFrozenPanes in Worksheet.Options) then begin
|
grow := GetGridRow(Worksheet.TopRow);
|
||||||
FrozenCols := Worksheet.LeftPaneWidth;
|
gcol := GetGridCol(Worksheet.LeftCol);
|
||||||
FrozenRows := Worksheet.TopPaneHeight;
|
actgrow := GetGridRow(Worksheet.ActiveCellRow);
|
||||||
end else begin
|
actgcol := GetGridCol(Worksheet.ActiveCellCol);
|
||||||
FrozenCols := 0;
|
AutoExpandToRow(grow, aeNavigation);
|
||||||
FrozenRows := 0;
|
AutoExpandToCol(gcol, aeNavigation);
|
||||||
|
if (grow <> Row) or (gcol <> Col) then
|
||||||
|
MoveExtend(false, gcol, grow);
|
||||||
|
inc(FLockSetup);
|
||||||
|
// Setup grid headers and col/row count
|
||||||
|
ShowHeaders := (soShowHeaders in Worksheet.Options);
|
||||||
|
ShowGridLines := (soShowGridLines in Worksheet.Options);
|
||||||
|
if (soHasFrozenPanes in Worksheet.Options) then begin
|
||||||
|
FrozenCols := Worksheet.LeftPaneWidth;
|
||||||
|
FrozenRows := Worksheet.TopPaneHeight;
|
||||||
|
end else begin
|
||||||
|
FrozenCols := 0;
|
||||||
|
FrozenRows := 0;
|
||||||
|
end;
|
||||||
|
case Worksheet.BiDiMode of
|
||||||
|
bdDefault: ParentBiDiMode := true;
|
||||||
|
bdLTR : begin
|
||||||
|
ParentBiDiMode := false;
|
||||||
|
BiDiMode := bdLeftToRight;
|
||||||
|
end;
|
||||||
|
bdRTL : begin
|
||||||
|
ParentBiDiMode := false;
|
||||||
|
BiDiMode := bdRightToLeft;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
dec(FLockSetup);
|
||||||
end;
|
end;
|
||||||
case Worksheet.BiDiMode of
|
Setup;
|
||||||
bdDefault: ParentBiDiMode := true;
|
// scroll the grid for top/left to be as stored in the sheet
|
||||||
bdLTR : begin
|
if (grow <> TopRow) or (gcol <> LeftCol) then
|
||||||
ParentBiDiMode := false;
|
begin
|
||||||
BiDiMode := bdLeftToRight;
|
TopRow := gRow;
|
||||||
end;
|
LeftCol := gCol;
|
||||||
bdRTL : begin
|
|
||||||
ParentBiDiMode := false;
|
|
||||||
BiDiMode := bdRightToLeft;
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
dec(FLockSetup);
|
// Select active cell
|
||||||
|
AutoExpandToRow(actgrow, aeNavigation);
|
||||||
|
AutoExpandToCol(actgcol, aeNavigation);
|
||||||
|
if (actgrow <> Row) or (actgcol <> Col) then
|
||||||
|
MoveExtend(false, actgcol, actgrow);
|
||||||
|
finally
|
||||||
|
EndUpdate;
|
||||||
end;
|
end;
|
||||||
Setup;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// Cell value or format changed
|
// Cell value or format changed
|
||||||
@ -4179,6 +4237,12 @@ begin
|
|||||||
// Worksheet zoom
|
// Worksheet zoom
|
||||||
if (lniWorksheetZoom in AChangedItems) and (Worksheet <> nil) then
|
if (lniWorksheetZoom in AChangedItems) and (Worksheet <> nil) then
|
||||||
AdaptToZoomFactor; // Reads value directly from Worksheet
|
AdaptToZoomFactor; // Reads value directly from Worksheet
|
||||||
|
|
||||||
|
{$IFDEF GRID_DEBUG}
|
||||||
|
if Worksheet <> nil then
|
||||||
|
DebugNotification('AFTER ListenerNotification WorksheetGrid "' + Worksheet.Name + '":');
|
||||||
|
{$ENDIF}
|
||||||
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{@@ ----------------------------------------------------------------------------
|
{@@ ----------------------------------------------------------------------------
|
||||||
@ -4498,6 +4562,8 @@ end;
|
|||||||
initial column widths and row heights.
|
initial column widths and row heights.
|
||||||
-------------------------------------------------------------------------------}
|
-------------------------------------------------------------------------------}
|
||||||
procedure TsCustomWorksheetGrid.Setup;
|
procedure TsCustomWorksheetGrid.Setup;
|
||||||
|
var
|
||||||
|
defColCount, defRowCount: Integer;
|
||||||
begin
|
begin
|
||||||
if csLoading in ComponentState then
|
if csLoading in ComponentState then
|
||||||
exit;
|
exit;
|
||||||
@ -4520,15 +4586,10 @@ begin
|
|||||||
end;
|
end;
|
||||||
end else
|
end else
|
||||||
if Worksheet <> nil then begin
|
if Worksheet <> nil then begin
|
||||||
if FHeaderCount = 0 then
|
defColCount := DEFAULT_COL_COUNT;
|
||||||
begin
|
defRowCount := DEFAULT_ROW_COUNT;
|
||||||
ColCount := Max(GetGridCol(Worksheet.GetLastColIndex), ColCount-1);
|
ColCount := Max(GetGridCol(Worksheet.GetLastColIndex)+1, defColCount) + FHeaderCount;
|
||||||
RowCount := Max(GetGridRow(Worksheet.GetLastRowIndex), RowCount-1);
|
RowCount := max(GetGridRow(Worksheet.GetLastRowIndex)+1, defRowCount) + FHeaderCount;
|
||||||
end else
|
|
||||||
begin
|
|
||||||
ColCount := Max(GetGridCol(Worksheet.GetLastColIndex) + 1, ColCount);
|
|
||||||
RowCount := Max(GetGridRow(Worksheet.GetLastRowIndex) + 1, RowCount);
|
|
||||||
end;
|
|
||||||
FixedCols := FFrozenCols + FHeaderCount;
|
FixedCols := FFrozenCols + FHeaderCount;
|
||||||
FixedRows := FFrozenRows + FHeaderCount;
|
FixedRows := FFrozenRows + FHeaderCount;
|
||||||
if ShowHeaders then begin
|
if ShowHeaders then begin
|
||||||
@ -4539,7 +4600,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
UpdateColWidths;
|
UpdateColWidths;
|
||||||
UpdateRowHeights;
|
UpdateRowHeights;
|
||||||
Invalidate;
|
//Invalidate; // wp: really needed? Might cause flicker
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{@@ ----------------------------------------------------------------------------
|
{@@ ----------------------------------------------------------------------------
|
||||||
@ -4681,6 +4742,15 @@ begin
|
|||||||
);
|
);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{@@ ----------------------------------------------------------------------------
|
||||||
|
Store the value of the TopLeft cell in the worksheet
|
||||||
|
-------------------------------------------------------------------------------}
|
||||||
|
procedure TsCustomWorksheetGrid.TopLeftChanged;
|
||||||
|
begin
|
||||||
|
inherited;
|
||||||
|
Worksheet.ScrollTo(GetWorkSheetRow(TopRow), GetWorksheetCol(LeftCol));
|
||||||
|
end;
|
||||||
|
|
||||||
{@@ ----------------------------------------------------------------------------
|
{@@ ----------------------------------------------------------------------------
|
||||||
Modifies the text that is show for cells which are too narrow to hold the
|
Modifies the text that is show for cells which are too narrow to hold the
|
||||||
entire text. The method follows the behavior of Excel and Open/LibreOffice:
|
entire text. The method follows the behavior of Excel and Open/LibreOffice:
|
||||||
|
Reference in New Issue
Block a user