From adbc5c7c2154647eb0ac0b43443831c9107649d5 Mon Sep 17 00:00:00 2001 From: wp_xxyyzz Date: Sat, 15 Aug 2015 14:24:31 +0000 Subject: [PATCH] fpspreadsheet: Fix TsWorksheetGrid to be correctly notified of worksheet changes if not connected to a WorkbookSource (suggested by rvk, http://forum.lazarus.freepascal.org/index.php/topic,29214.msg184168.html#msg184168). Fix related demos. git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@4272 8e941d3f-bd1b-0410-a28a-d453659cc2b4 --- .../visual/fpsctrls_no_install/demo_ctrls.lpi | 1 - .../examples/visual/fpsgrid/fpsgrid.lpi | 1 - .../examples/visual/fpsgrid/mainform.lfm | 29 +++++++ .../examples/visual/fpsgrid/mainform.pas | 14 +++- .../visual/fpsgrid_no_install/fpsgrid.lpi | 1 - .../visual/fpsgrid_no_install/mainfrm.lfm | 25 ++++++ .../visual/fpsgrid_no_install/mainfrm.pas | 10 +++ .../examples/visual/spready/mainform.pas | 2 +- .../fpspreadsheet/fpspreadsheetgrid.pas | 79 +++++++++++++------ 9 files changed, 132 insertions(+), 30 deletions(-) diff --git a/components/fpspreadsheet/examples/visual/fpsctrls_no_install/demo_ctrls.lpi b/components/fpspreadsheet/examples/visual/fpsctrls_no_install/demo_ctrls.lpi index 8f6cb9564..3f2947184 100644 --- a/components/fpspreadsheet/examples/visual/fpsctrls_no_install/demo_ctrls.lpi +++ b/components/fpspreadsheet/examples/visual/fpsctrls_no_install/demo_ctrls.lpi @@ -44,7 +44,6 @@ - diff --git a/components/fpspreadsheet/examples/visual/fpsgrid/fpsgrid.lpi b/components/fpspreadsheet/examples/visual/fpsgrid/fpsgrid.lpi index 0943006f2..ae3177245 100644 --- a/components/fpspreadsheet/examples/visual/fpsgrid/fpsgrid.lpi +++ b/components/fpspreadsheet/examples/visual/fpsgrid/fpsgrid.lpi @@ -48,7 +48,6 @@ - diff --git a/components/fpspreadsheet/examples/visual/fpsgrid/mainform.lfm b/components/fpspreadsheet/examples/visual/fpsgrid/mainform.lfm index 72cb06366..c965f759c 100644 --- a/components/fpspreadsheet/examples/visual/fpsgrid/mainform.lfm +++ b/components/fpspreadsheet/examples/visual/fpsgrid/mainform.lfm @@ -45,6 +45,31 @@ object Form1: TForm1 OnClick = BtnNewClick TabOrder = 2 end + object Label2: TLabel + Left = 296 + Height = 15 + Top = 13 + Width = 132 + Caption = 'New text for cell [AB110]:' + ParentColor = False + end + object EdNewCellText: TEdit + Left = 451 + Height = 23 + Top = 9 + Width = 104 + TabOrder = 3 + Text = 'Test' + end + object BtnEnterText: TButton + Left = 566 + Height = 25 + Top = 8 + Width = 75 + Caption = 'Set text' + OnClick = BtnEnterTextClick + TabOrder = 4 + end end object WorksheetGrid: TsWorksheetGrid Left = 0 @@ -98,6 +123,10 @@ object Form1: TForm1 Text = 'Sheet 1' end end + object sWorkbookSource1: TsWorkbookSource + AutoDetectFormat = False + Options = [] + end object OpenDialog: TOpenDialog DefaultExt = '.xls' Filter = 'Excel spreadsheet (*.xls)|*.xls|Excel XML spreadsheet (*.xlsx)|*.xlsx|LibreOffice/OpenOffice spreadsheet (*.ods)|*.ods|Wikitable (pipes) (.wikitable_pipes)|.wikitable_pipes|All files (*.*)|*.*' diff --git a/components/fpspreadsheet/examples/visual/fpsgrid/mainform.pas b/components/fpspreadsheet/examples/visual/fpsgrid/mainform.pas index 8794027e7..fa0267a39 100644 --- a/components/fpspreadsheet/examples/visual/fpsgrid/mainform.pas +++ b/components/fpspreadsheet/examples/visual/fpsgrid/mainform.pas @@ -6,8 +6,8 @@ interface uses Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs, - StdCtrls, Menus, ExtCtrls, ActnList, Spin, Buttons, - ButtonPanel, fpspreadsheetgrid, fpspreadsheet, {%H-}fpsallformats; + StdCtrls, Menus, ExtCtrls, ActnList, Spin, Buttons, ButtonPanel, + fpspreadsheetgrid, fpspreadsheet, fpsallformats, fpspreadsheetctrls; type @@ -17,16 +17,21 @@ type BtnOpen: TButton; BtnSave: TButton; BtnNew: TButton; + BtnEnterText: TButton; + EdNewCellText: TEdit; + Label2: TLabel; SheetsCombo: TComboBox; Label1: TLabel; OpenDialog: TOpenDialog; Panel1: TPanel; Panel2: TPanel; SaveDialog: TSaveDialog; + sWorkbookSource1: TsWorkbookSource; WorksheetGrid: TsWorksheetGrid; procedure BtnNewClick(Sender: TObject); procedure BtnOpenClick(Sender: TObject); procedure BtnSaveClick(Sender: TObject); + procedure BtnEnterTextClick(Sender: TObject); procedure SheetsComboSelect(Sender: TObject); private { private declarations } @@ -141,6 +146,11 @@ begin end; end; +procedure TForm1.BtnEnterTextClick(Sender: TObject); +begin + WorksheetGrid.Worksheet.WriteText(109, 27, EdNewCellText.Text); +end; + procedure TForm1.SheetsComboSelect(Sender: TObject); begin WorksheetGrid.SelectSheetByIndex(SheetsCombo.ItemIndex); diff --git a/components/fpspreadsheet/examples/visual/fpsgrid_no_install/fpsgrid.lpi b/components/fpspreadsheet/examples/visual/fpsgrid_no_install/fpsgrid.lpi index c74c17e41..93fe2444a 100644 --- a/components/fpspreadsheet/examples/visual/fpsgrid_no_install/fpsgrid.lpi +++ b/components/fpspreadsheet/examples/visual/fpsgrid_no_install/fpsgrid.lpi @@ -67,7 +67,6 @@ - diff --git a/components/fpspreadsheet/examples/visual/fpsgrid_no_install/mainfrm.lfm b/components/fpspreadsheet/examples/visual/fpsgrid_no_install/mainfrm.lfm index 139961474..f5870dc8c 100644 --- a/components/fpspreadsheet/examples/visual/fpsgrid_no_install/mainfrm.lfm +++ b/components/fpspreadsheet/examples/visual/fpsgrid_no_install/mainfrm.lfm @@ -45,6 +45,31 @@ object Form1: TForm1 OnClick = BtnSaveClick TabOrder = 2 end + object Label1: TLabel + Left = 288 + Height = 15 + Top = 11 + Width = 144 + Caption = 'Enter value for cell [AB110]:' + ParentColor = False + end + object EdCellValue: TEdit + Left = 439 + Height = 23 + Top = 7 + Width = 137 + TabOrder = 3 + Text = 'Test' + end + object BtnEnterText: TButton + Left = 584 + Height = 25 + Top = 6 + Width = 75 + Caption = 'Enter text' + OnClick = BtnEnterTextClick + TabOrder = 4 + end end object TabControl: TTabControl Left = 0 diff --git a/components/fpspreadsheet/examples/visual/fpsgrid_no_install/mainfrm.pas b/components/fpspreadsheet/examples/visual/fpsgrid_no_install/mainfrm.pas index 42f45c22b..9af0c669d 100644 --- a/components/fpspreadsheet/examples/visual/fpsgrid_no_install/mainfrm.pas +++ b/components/fpspreadsheet/examples/visual/fpsgrid_no_install/mainfrm.pas @@ -17,10 +17,14 @@ type BtnNew: TButton; BtnLoad: TButton; BtnSave: TButton; + BtnEnterText: TButton; ButtonPanel: TPanel; + EdCellValue: TEdit; + Label1: TLabel; OpenDialog: TOpenDialog; SaveDialog: TSaveDialog; TabControl: TTabControl; + procedure BtnEnterTextClick(Sender: TObject); procedure BtnLoadClick(Sender: TObject); procedure BtnNewClick(Sender: TObject); procedure BtnSaveClick(Sender: TObject); @@ -85,6 +89,12 @@ begin end; end; +procedure TForm1.BtnEnterTextClick(Sender: TObject); +begin + Grid.Worksheet.WriteText(109, 27, EdCellValue.Text); + Grid.Worksheet.SelectCell(109, 27); +end; + procedure TForm1.BtnNewClick(Sender: TObject); begin TabControl.Tabs.Clear; diff --git a/components/fpspreadsheet/examples/visual/spready/mainform.pas b/components/fpspreadsheet/examples/visual/spready/mainform.pas index 5f91945bf..28cc0b922 100644 --- a/components/fpspreadsheet/examples/visual/spready/mainform.pas +++ b/components/fpspreadsheet/examples/visual/spready/mainform.pas @@ -927,7 +927,7 @@ var clrName: String; i: Integer; begin - if WorksheetGrid.Workbook <> nil then begin + if (WorksheetGrid.Workbook <> nil) and (FPalette <> nil) then begin Items.Clear; Items.AddObject('no fill', TObject(PtrInt(clNone))); for i:=0 to FPalette.Count-1 do begin diff --git a/components/fpspreadsheet/fpspreadsheetgrid.pas b/components/fpspreadsheet/fpspreadsheetgrid.pas index 46f21d44f..59b5f866b 100644 --- a/components/fpspreadsheet/fpspreadsheetgrid.pas +++ b/components/fpspreadsheet/fpspreadsheetgrid.pas @@ -45,9 +45,10 @@ type private { Private declarations } FWorkbookSource: TsWorkbookSource; - FOwnedWorkbook: TsWorkbook; - FOwnsWorkbook: Boolean; - FOwnedWorksheet: TsWorksheet; + FInternalWorkbookSource: TsWorkbookSource; +// FOwnedWorkbook: TsWorkbook; +// FOwnsWorkbook: Boolean; +// FOwnedWorksheet: TsWorksheet; FHeaderCount: Integer; FInitColCount: Integer; FInitRowCount: Integer; @@ -103,6 +104,7 @@ type function GetVertAlignment(ACol, ARow: Integer): TsVertAlignment; function GetVertAlignments(ARect: TGridRect): TsVertAlignment; function GetWorkbook: TsWorkbook; + function GetWorkbookSource: TsWorkbookSource; function GetWorksheet: TsWorksheet; function GetWordwrap(ACol, ARow: Integer): Boolean; function GetWordwraps(ARect: TGridRect): Boolean; @@ -180,7 +182,7 @@ type } procedure KeyDown(var Key : Word; Shift : TShiftState); override; procedure Loaded; override; - procedure LoadFromWorksheet(AWorksheet: TsWorksheet); +// procedure LoadFromWorksheet(AWorksheet: TsWorksheet); procedure MouseDown(Button: TMouseButton; Shift:TShiftState; X,Y:Integer); override; procedure MouseMove(Shift: TShiftState; X, Y: Integer); override; procedure MouseUp(Button: TMouseButton; Shift:TShiftState; X,Y:Integer); override; @@ -846,6 +848,7 @@ end; -------------------------------------------------------------------------------} constructor TsCustomWorksheetGrid.Create(AOwner: TComponent); begin + FInternalWorkbookSource := TsWorkbookSource.Create(self); //AOwner); inherited Create(AOwner); AutoAdvance := aaDown; ExtendedSelect := true; @@ -856,7 +859,7 @@ begin FHyperlinkTimer := TTimer.Create(self); FHyperlinkTimer.Interval := HYPERLINK_TIMER_INTERVAL; FHyperlinkTimer.OnTimer := @HyperlinkTimerElapsed; - FOwnsWorkbook := true; + SetWorkbookSource(FInternalWorkbookSource); {$IFNDEF FPS_NO_GRID_MULTISELECT} RangeSelectMode := rsmMulti; {$ENDIF} @@ -867,8 +870,11 @@ end; -------------------------------------------------------------------------------} destructor TsCustomWorksheetGrid.Destroy; begin - if FWorkbookSource <> nil then FWorkbookSource.RemoveListener(self); - if FOwnsWorkbook then FreeAndNil(FOwnedWorkbook); + SetWorkbookSource(nil); + if FInternalWorkbookSource <> nil then + FInternalWorkbookSource.RemoveListener(self); // will be destroyed automatically +// FreeAndNil(FInternalWorkbookSource); +// end; FreeAndNil(FCellFont); inherited Destroy; end; @@ -1265,6 +1271,12 @@ end; -------------------------------------------------------------------------------} procedure TsCustomWorksheetGrid.CreateNewWorkbook; begin + GetWorkbookSource.CreateNewWorkbook; + if FReadFormulas then + Workbook.Options := Workbook.Options + [boReadFormulas] else + Workbook.Options := Workbook.Options - [boReadFormulas]; + SetAutoCalc(FAutoCalc); + { if FOwnsWorkbook then FreeAndNil(FOwnedWorkbook); @@ -1280,6 +1292,7 @@ begin FOwnedWorkbook.Options := FOwnedWorkbook.Options - [boReadFormulas]; SetAutoCalc(FAutoCalc); end; + } end; {@@ ---------------------------------------------------------------------------- @@ -3396,7 +3409,7 @@ begin // CreateNewWorkbook; NewWorkbook(FInitColCount, FInitRowCount); end; - + (* {@@ ---------------------------------------------------------------------------- Loads the worksheet into the grid and displays its contents. @@ -3407,6 +3420,7 @@ begin if FWorkbookSource <> nil then exit; + GetWorkbookSource.LoadFro FOwnedWorksheet := AWorksheet; if FOwnedWorksheet <> nil then begin inc(FLockSetup); @@ -3427,7 +3441,7 @@ begin end; Setup; end; - + *) {@@ ---------------------------------------------------------------------------- Creates a new workbook and loads the given file into it. The file is assumed to have the given file format. Shows the sheet with the given sheet index. @@ -3440,6 +3454,8 @@ end; procedure TsCustomWorksheetGrid.LoadFromSpreadsheetFile(AFileName: string; AFormat: TsSpreadsheetFormat; AWorksheetIndex: Integer); begin + GetWorkbookSource.LoadfromSpreadsheetFile(AFileName, AFormat, AWorksheetIndex); + { if FOwnsWorkbook then FreeAndNil(FOwnedWorkbook); @@ -3456,6 +3472,7 @@ begin EndUpdate; end; end; + } end; {@@ ---------------------------------------------------------------------------- @@ -3469,6 +3486,8 @@ end; procedure TsCustomWorksheetGrid.LoadFromSpreadsheetFile(AFileName: string; AWorksheetIndex: Integer); begin + GetWorkbookSource.LoadFromSpreadsheetFile(AFileName, AWorksheetIndex); + { if FOwnsWorkbook then FreeAndNil(FOwnedWorkbook); @@ -3485,6 +3504,7 @@ begin EndUpdate; end; end; + } end; {@@ ---------------------------------------------------------------------------- @@ -3711,6 +3731,8 @@ end; -------------------------------------------------------------------------------} procedure TsCustomWorksheetGrid.NewWorkbook(AColCount, ARowCount: Integer); begin + GetWorkbookSource.CreateNewWorkbook; + { if FOwnsWorkbook then FreeAndNil(FOwnedWorkbook); @@ -3731,6 +3753,7 @@ begin EndUpdate; end; end; + } end; {@@ ---------------------------------------------------------------------------- @@ -3810,8 +3833,11 @@ end; -------------------------------------------------------------------------------} procedure TsCustomWorksheetGrid.SelectSheetByIndex(AIndex: Integer); begin + GetWorkbookSource.SelectWorksheet(Workbook.GetWorksheetByIndex(AIndex)); + { if Workbook <> nil then LoadFromWorksheet(Workbook.GetWorksheetByIndex(AIndex)); + } end; {@@ ---------------------------------------------------------------------------- @@ -3882,17 +3908,21 @@ begin if AValue = FWorkbookSource then exit; - if FOwnsWorkbook then - FreeAndNil(FOwnedWorkbook); - if FWorkbookSource <> nil then FWorkbookSource.RemoveListener(self); - FWorkbookSource := AValue; - if FWorkbookSource <> nil then - FWorkbookSource.AddListener(self); + FInternalWorkbookSource.RemoveListener(self); - FOwnsWorkbook := (FWorkbookSource = nil); - if not (csDestroying in ComponentState) then + if (AValue = FInternalWorkbookSource) or (AValue = nil) then + begin + FWorkbookSource := nil; + FInternalWorkbookSource.AddListener(self); + end else + begin + FWorkbookSource := AValue; + FWorkbookSource.AddListener(self); + end; + + if not (csDestroying in ComponentState) and Assigned(Parent) then ListenerNotification([lniWorksheet, lniSelection]); end; @@ -4347,19 +4377,20 @@ begin end; function TsCustomWorksheetGrid.GetWorkbook: TsWorkbook; +begin + Result := GetWorkbookSource.Workbook; +end; + +function TsCustomWorksheetGrid.GetWorkbookSource: TsWorkbookSource; begin if FWorkbookSource <> nil then - Result := FWorkbookSource.Workbook - else - Result := FOwnedWorkbook; + Result := FWorkbookSource else + Result := FInternalWorkbookSource; end; function TsCustomWorksheetGrid.GetWorksheet: TsWorksheet; begin - if FWorkbookSource <> nil then - Result := FWorkbooksource.Worksheet - else - Result := FOwnedWorksheet; + Result := GetWorkbookSource.Worksheet; end; function TsCustomWorksheetGrid.GetWordwrap(ACol, ARow: Integer): Boolean;