You've already forked lazarus-ccr
fpspreadsheet: Avoid flicker of TsTabControl when new workbook is opened or worksheets are added manually. Fix some bugs in the notification system.
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@3758 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -942,6 +942,7 @@ type
|
||||
FCalculationLock: Integer;
|
||||
FOptions: TsWorkbookOptions;
|
||||
FActiveWorksheet: TsWorksheet;
|
||||
FOnOpenWorkbook: TNotifyEvent;
|
||||
FOnWriteCellData: TsWorkbookWriteCellDataEvent;
|
||||
FOnReadCellData: TsWorkbookReadCellDataEvent;
|
||||
FOnChangeWorksheet: TsWorksheetEvent;
|
||||
@ -949,6 +950,7 @@ type
|
||||
FOnRemoveWorksheet: TsRemoveWorksheetEvent;
|
||||
FOnSelectWorksheet: TsWorksheetEvent;
|
||||
FFileName: String;
|
||||
FLockCount: Integer;
|
||||
FLog: TStringList;
|
||||
|
||||
{ Setter/Getter }
|
||||
@ -1063,6 +1065,8 @@ type
|
||||
property OnAddWorksheet: TsWorksheetEvent read FOnAddWorksheet write FOnAddWorksheet;
|
||||
{@@ This event fires whenever a worksheet is changed }
|
||||
property OnChangeWorksheet: TsWorksheetEvent read FOnChangeWorksheet write FOnChangeWorksheet;
|
||||
{@@ This event fires whenever a workbook is loaded }
|
||||
property OnOpenWorkbook: TNotifyEvent read FOnOpenWorkbook write FOnOpenWorkbook;
|
||||
{@@ This event fires when a worksheet is deleted }
|
||||
property OnRemoveWorksheet: TsRemoveWorksheetEvent read FOnRemoveWorksheet write FOnRemoveWorksheet;
|
||||
{@@ This event fires when a worksheet is made "active"}
|
||||
@ -3366,7 +3370,7 @@ begin
|
||||
if (FWorkbook <> nil) then //and FWorkbook.ValidWorksheetName(AName) then
|
||||
begin
|
||||
FName := AName;
|
||||
if Assigned(FWorkbook.FOnChangeWorksheet) then
|
||||
if (FWorkbook.FLockCount = 0) and Assigned(FWorkbook.FOnChangeWorksheet) then
|
||||
FWorkbook.FOnChangeWorksheet(FWorkbook, self);
|
||||
end;
|
||||
end;
|
||||
@ -6495,6 +6499,7 @@ procedure TsWorkbook.ReadFromFile(AFileName: string;
|
||||
AFormat: TsSpreadsheetFormat);
|
||||
var
|
||||
AReader: TsCustomSpreadReader;
|
||||
ok: Boolean;
|
||||
begin
|
||||
if not FileExists(AFileName) then
|
||||
raise Exception.CreateFmt(rsFileNotFound, [AFileName]);
|
||||
@ -6503,11 +6508,20 @@ begin
|
||||
try
|
||||
FFileName := AFileName;
|
||||
PrepareBeforeReading;
|
||||
ok := false;
|
||||
inc(FLockCount); // This locks various notifications from being sent
|
||||
try
|
||||
AReader.ReadFromFile(AFileName, Self);
|
||||
ok := true;
|
||||
UpdateCaches;
|
||||
if (boAutoCalc in Options) then
|
||||
Recalc;
|
||||
FFormat := AFormat;
|
||||
finally
|
||||
dec(FLockCount);
|
||||
if ok and Assigned(FOnOpenWorkbook) then // ok is true if file has been read successfully
|
||||
FOnOpenWorkbook(self); // send common notification
|
||||
end;
|
||||
finally
|
||||
AReader.Free;
|
||||
end;
|
||||
@ -6596,11 +6610,21 @@ procedure TsWorkbook.ReadFromStream(AStream: TStream;
|
||||
AFormat: TsSpreadsheetFormat);
|
||||
var
|
||||
AReader: TsCustomSpreadReader;
|
||||
ok: Boolean;
|
||||
begin
|
||||
AReader := CreateSpreadReader(AFormat);
|
||||
try
|
||||
PrepareBeforeReading;
|
||||
inc(FLockCount);
|
||||
try
|
||||
ok := false;
|
||||
AReader.ReadFromStream(AStream, Self);
|
||||
ok := true;
|
||||
finally
|
||||
dec(FLockCount);
|
||||
if ok and Assigned(FOnOpenWorkbook) then
|
||||
FOnOpenWorkbook(self);
|
||||
end;
|
||||
UpdateCaches;
|
||||
if (boAutoCalc in Options) then
|
||||
Recalc;
|
||||
@ -6708,15 +6732,34 @@ end;
|
||||
function TsWorkbook.AddWorksheet(AName: string;
|
||||
ReplaceDuplicateName: Boolean = false): TsWorksheet;
|
||||
begin
|
||||
// Check worksheet name
|
||||
if not ValidWorksheetName(AName, ReplaceDuplicateName) then
|
||||
raise Exception.CreateFmt(rsInvalidWorksheetName, [AName]);
|
||||
|
||||
// Create worksheet...
|
||||
Result := TsWorksheet.Create;
|
||||
|
||||
Result.FWorkbook := Self; // Must be before "SetName" needing the workbook
|
||||
// Add it to the internal worksheet list
|
||||
FWorksheets.Add(Pointer(Result));
|
||||
|
||||
// Remember the workbook to which it belongs (This must occur before
|
||||
// setting the workbook name because the workbook is needed there).
|
||||
Result.FWorkbook := Self;
|
||||
|
||||
// Set the name of the new worksheet.
|
||||
// For this we turn off notification of listeners. This is not necessary here
|
||||
// because it will be repeated at end when OnAddWorksheet is executed below.
|
||||
inc(FLockCount);
|
||||
try
|
||||
Result.Name := AName;
|
||||
if Assigned(FOnAddWorksheet) then FOnAddWorksheet(self, Result);
|
||||
finally
|
||||
dec(FLockCount);
|
||||
end;
|
||||
|
||||
// Send notification for new worksheet to listeners. They get the worksheet
|
||||
// name here as well.
|
||||
if (FLockCount = 0) and Assigned(FOnAddWorksheet) then
|
||||
FOnAddWorksheet(self, Result);
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
|
@ -73,6 +73,7 @@ type
|
||||
AFormat: TsSpreadsheetFormat; AWorksheetIndex: Integer = 0);
|
||||
procedure SetFileName(const AFileName: TFileName);
|
||||
procedure SetOptions(AValue: TsWorkbookOptions);
|
||||
procedure WorkbookOpenedHandler(Sender: TObject);
|
||||
procedure WorksheetAddedHandler(Sender: TObject; ASheet: TsWorksheet);
|
||||
procedure WorksheetChangedHandler(Sender: TObject; ASheet: TsWorksheet);
|
||||
procedure WorksheetRemovedHandler(Sender: TObject; ASheetIndex: Integer);
|
||||
@ -473,7 +474,7 @@ begin
|
||||
SelectWorksheet(FWorksheet);
|
||||
|
||||
// notify listeners
|
||||
NotifyListeners([lniWorkbook, lniWorksheet, lniSelection]);
|
||||
// NotifyListeners([lniWorkbook, lniWorksheet, lniSelection]);
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
@ -571,6 +572,7 @@ begin
|
||||
FreeAndNil(FWorkbook);
|
||||
FWorksheet := nil;
|
||||
FWorkbook := TsWorkbook.Create;
|
||||
FWorkbook.OnOpenWorkbook := @WorkbookOpenedHandler;
|
||||
FWorkbook.OnAddWorksheet := @WorksheetAddedHandler;
|
||||
FWorkbook.OnChangeWorksheet := @WorksheetChangedHandler;
|
||||
FWorkbook.OnRemoveWorksheet := @WorksheetRemovedHandler;
|
||||
@ -881,6 +883,16 @@ begin
|
||||
FPendingOperation := AOperation;
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Event handler called whenever a new workbook is opened.
|
||||
-------------------------------------------------------------------------------}
|
||||
procedure TsWorkbookSource.WorkbookOpenedHandler(Sender: TObject);
|
||||
begin
|
||||
Unused(Sender);
|
||||
NotifyListeners([lniWorkbook]);
|
||||
SelectWorksheet(FWorkbook.GetFirstWorksheet);
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Event handler called whenever a new worksheet is added to the workbook
|
||||
|
||||
@ -938,6 +950,7 @@ begin
|
||||
sheet := Workbook.GetWorksheetbyIndex(ASheetIndex);
|
||||
end else
|
||||
sheet := FWorksheet;
|
||||
FWorksheet := sheet; // is needed by listeners!
|
||||
NotifyListeners([lniWorkbook]);
|
||||
SelectWorksheet(sheet);
|
||||
end;
|
||||
@ -1453,8 +1466,9 @@ var
|
||||
activeCell: PCell;
|
||||
begin
|
||||
Unused(AData);
|
||||
if worksheet = nil then
|
||||
if (Worksheet = nil) or ([lniCell, lniSelection]*AChangedItems = []) then
|
||||
exit;
|
||||
|
||||
activeCell := Worksheet.FindCell(Worksheet.ActiveCellRow, Worksheet.ActiveCellCol);
|
||||
if ((lniCell in AChangedItems) and (PCell(AData) = activeCell)) or
|
||||
(lniSelection in AChangedItems)
|
||||
|
Reference in New Issue
Block a user