ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/public/ibx/branches/journaling/ibcontrols/IBDynamicGrid.pas
(Generate patch)

Comparing ibx/trunk/ibcontrols/IBDynamicGrid.pas (file contents):
Revision 21 by tony, Thu Feb 26 10:33:34 2015 UTC vs.
Revision 35 by tony, Tue Jan 26 14:38:47 2016 UTC

# Line 15 | Line 15
15   *
16   *  The Initial Developer of the Original Code is Tony Whyman.
17   *
18 < *  The Original Code is (C) 2011 Tony Whyman, MWA Software
18 > *  The Original Code is (C) 2015 Tony Whyman, MWA Software
19   *  (http://www.mwasoftware.co.uk).
20   *
21   *  All Rights Reserved.
# Line 23 | Line 23
23   *  Contributor(s): ______________________________________.
24   *
25   *)
26 +
27   unit IBDynamicGrid;
28  
29   {$mode objfpc}{$H+}
# Line 31 | Line 32 | interface
32  
33   uses
34    Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, DBGrids, DB,
35 <  IBSqlParser, Grids, IBLookupComboEditBox, LMessages, StdCtrls, ExtCtrls;
35 >  IBSQLParser, Grids, IBLookupComboEditBox, LMessages, StdCtrls, ExtCtrls,
36 >  IBCustomDataSet;
37  
38   type
39    {
# Line 55 | Line 57 | type
57    TOnUpdateSortOrder = procedure (Sender: TObject; ColIndex: integer; var OrderBy: string) of Object;
58    TKeyDownHandler = procedure (Sender: TObject; var Key: Word;  Shift: TShiftState; var Done: boolean) of object;
59  
58  { TDynamicGridDataLink }
59
60  TDynamicGridDataLink = class(TDataLink)
61  private
62    FOwner: TIBDynamicGrid;
63  protected
64    procedure DataEvent(Event: TDataEvent; Info: Ptrint); override;
65    procedure DataSetScrolled(Distance: Integer); override;
66  public
67    constructor Create(AOwner: TIBDynamicGrid);
68  end;
69
60    { TDBDynamicGridColumn }
61  
62    TDBDynamicGridColumn = class(TColumn)
# Line 102 | Line 92 | type
92      FListSource: TDataSource;
93      FOnAutoInsert: TAutoInsert;
94      FOnCanAutoInsert: TCanAutoInsert;
95 +    FOnCloseUp: TNotifyEvent;
96      FOnDrawItem: TDrawItemEvent;
97      FOwner: TIBDynamicGridColumn;
98      FRelationName: string;
# Line 128 | Line 119 | type
119      property Style: TComboBoxStyle read FStyle write FStyle default csDropDown;
120      property OnAutoInsert: TAutoInsert read FOnAutoInsert write FOnAutoInsert;
121      property OnCanAutoInsert: TCanAutoInsert read FOnCanAutoInsert write FOnCanAutoInsert;
122 +    property OnCloseUp: TNotifyEvent read FOnCloseUp write FOnCloseUp;
123      property OnDrawItem: TDrawItemEvent read FOnDrawItem write FOnDrawItem;
124   end;
125  
# Line 162 | Line 154 | end;
154      procedure WndProc(var TheMessage : TLMessage); override;
155      procedure CloseUp; override;
156      procedure KeyDown(var Key : Word; Shift : TShiftState); override;
157 +    procedure Loaded; override;
158      procedure msg_GetValue(var Msg: TGridMessage); message GM_GETVALUE;
159      procedure msg_SetGrid(var Msg: TGridMessage); message GM_SETGRID;
160      procedure msg_SetValue(var Msg: TGridMessage); message GM_SETVALUE;
# Line 187 | Line 180 | end;
180      FWeHaveFocus: boolean;
181      FHidingEditorPanel: boolean;
182      FAllowHide: boolean;
183 +    FMouseDown: boolean;
184 +    function ActiveControl: TControl;
185      procedure DoShowEditorPanel(Data: PtrInt);
186      procedure PositionTotals;
187      procedure KeyDownHandler(Sender: TObject; var Key: Word; Shift: TShiftState);
188 +    procedure PerformEditorHide(Data: PtrInt);
189      procedure SetEditorPanel(AValue: TWinControl);
190    protected
191      procedure ChangeBounds(ALeft, ATop, AWidth, AHeight: integer; KeepBase: boolean); override;
# Line 219 | Line 215 | end;
215      constructor Create(TheComponent: TComponent); override;
216      destructor Destroy ;override;
217      procedure ResizeColumns;
218 +    property VisibleRowCount;
219    published
220      property EditorPanel: TWinControl read FEditorPanel write SetEditorPanel;
221      property ExpandEditorPanelBelowRow: boolean read FExpandEditorPanelBelowRow write FExpandEditorPanelBelowRow;
# Line 228 | Line 225 | end;
225      property OnKeyDownHander: TKeyDownHandler read FOnKeyDownHander write FOnKeyDownHander;
226   end;
227  
228 +  {TIBGridControlLink}
229 +
230 +  TIBGridControlLink = class(TIBControlLink)
231 +  private
232 +    FOwner: TIBDynamicGrid;
233 +  protected
234 +    procedure UpdateSQL(Sender: TObject); override;
235 +  public
236 +    constructor Create(AOwner: TIBDynamicGrid);
237 +  end;
238 +
239 +  TLocationArray = array of variant;
240 +  PLocationArray = ^TLocationArray;
241 +  TOnRestorePosition = procedure(Sender: TObject; Location: PLocationArray) of object;
242 +
243    { TIBDynamicGrid }
244  
245    TIBDynamicGrid = class(TDBDynamicGrid)
246    private
247      { Private declarations }
248      FAllowColumnSort: boolean;
249 <    FDataLink: TDynamicGridDataLink;
249 >    FIBControlLink: TIBGridControlLink;
250      FOnColumnHeaderClick: TOnColumnHeaderClick;
251 +    FOnRestorePosition: TOnRestorePosition;
252      FOnUpdateSortOrder: TOnUpdateSortOrder;
253      FDefaultPositionAtEnd: boolean;
254      FDescending: boolean;
# Line 243 | Line 256 | end;
256      FLastColIndex: integer;
257      FIndexFieldNames: string;
258      FIndexFieldsList: TStringList;
259 <    FBookmark: array of variant;
259 >    FBookmark: TLocationArray;
260      FDBLookupCellEditor: TDBLookupCellEditor;
261      FActive: boolean;
262      procedure ColumnHeaderClick(Index: integer);
263      function GetDataSource: TDataSource;
264      function GetEditorBorderStyle: TBorderStyle;
265 +    procedure IBControlLinkChanged;
266      procedure SetDataSource(AValue: TDataSource);
267      procedure SetEditorBorderStyle(AValue: TBorderStyle);
268      procedure ProcessColumns;
269      procedure SetIndexFieldNames(AValue: string);
270      procedure UpdateSQL(Sender: TObject; Parser: TSelectSQLParser);
271      procedure UpdateSortColumn(Sender: TObject);
272 <    procedure DataSetScrolled(Sender: TObject);
273 <    procedure RestorePosition(Data: PtrInt);
272 >    procedure RestorePosition;
273 >    procedure SavePosition;
274      procedure DoReOpen(Data: PtrInt);
275      procedure SetupEditor(aEditor: TDBLookupCellEditor; aCol: integer);
276    protected
# Line 266 | Line 280 | end;
280      function  CreateColumns: TGridColumns; override;
281      procedure MouseDown(Button: TMouseButton; Shift:TShiftState; X,Y:Integer); override;
282      procedure LinkActive(Value: Boolean); override;
283 +    procedure MoveSelection; override;
284      procedure Notification(AComponent: TComponent; Operation: TOperation); override;
285      procedure UpdateActive; override;
286    public
# Line 283 | Line 298 | end;
298      property DefaultPositionAtEnd: boolean read  FDefaultPositionAtEnd write FDefaultPositionAtEnd;
299      property IndexFieldNames: string read FIndexFieldNames write SetIndexFieldNames;
300      property OnColumnHeaderClick: TOnColumnHeaderClick read FOnColumnHeaderClick write FOnColumnHeaderClick;
301 +    property OnRestorePosition: TOnRestorePosition read FOnRestorePosition write FOnRestorePosition;
302      property OnUpdateSortOrder: TOnUpdateSortOrder read FOnUpdateSortOrder write FOnUpdateSortOrder;
303   end;
304  
305   implementation
306  
307 < uses Math, IBQuery, IBCustomDataSet, LCLType;
307 > uses Math, IBQuery, LCLType;
308 >
309 > { TIBGridControlLink }
310 >
311 > constructor TIBGridControlLink.Create(AOwner: TIBDynamicGrid);
312 > begin
313 >  inherited Create;
314 >  FOwner := AOwner;
315 > end;
316 >
317 > procedure TIBGridControlLink.UpdateSQL(Sender: TObject);
318 > begin
319 >  FOwner.UpdateSQL(self,TIBParserDataSet(Sender).Parser)
320 > end;
321  
322   { TDBLookupProperties }
323  
# Line 335 | Line 364 | begin
364    FResizing := true;
365    try
366      ColSum := 0;
338    for I := 0 to  ColCount - 1 do
339       ColSum := ColSum + ColWidths[I];
367  
368 <    if Colsum <> ClientWidth then
368 >    if (ColCount = 1) and TDBDynamicGridColumn(Columns[0]).AutoSizeColumn then
369 >      Columns[0].Width := ClientWidth
370 >    else
371      begin
372 <      ResizeColCount := 0;
373 <      for I := 0 to Columns.Count -1 do
374 <        if TDBDynamicGridColumn(Columns[I]).AutoSizeColumn then
375 <        begin
376 <          Inc(ResizeColCount);
377 <          Colsum := Colsum + TDBDynamicGridColumn(Columns[I]).DesignWidth - Columns[I].Width;
378 <          Columns[I].Width := TDBDynamicGridColumn(Columns[I]).DesignWidth;
379 <        end;
380 <
381 <        if (Colsum < ClientWidth) and (ResizeColCount > 0) then
382 <        begin
383 <          adjustment := (ClientWidth - ColSum) div ResizeColCount;
384 <          n := (ClientWidth - ColSum) mod ResizeColCount;
385 <
386 <          for I := 0 to Columns.Count -1 do
387 <            if TDBDynamicGridColumn(Columns[I]).AutoSizeColumn then
388 <            begin
389 <              if I = 0 then
390 <                Columns[I].Width := Columns[I].Width + adjustment + n
391 <              else
392 <                Columns[I].Width := Columns[I].Width + adjustment;
393 <            end;
394 <        end;
372 >      for I := 0 to  ColCount - 1 do
373 >         ColSum := ColSum + ColWidths[I];
374 >
375 >      if Colsum <> ClientWidth then
376 >      begin
377 >        ResizeColCount := 0;
378 >        for I := 0 to Columns.Count -1 do
379 >          if TDBDynamicGridColumn(Columns[I]).AutoSizeColumn then
380 >          begin
381 >            Inc(ResizeColCount);
382 >            Colsum := Colsum + TDBDynamicGridColumn(Columns[I]).DesignWidth - Columns[I].Width;
383 >            Columns[I].Width := TDBDynamicGridColumn(Columns[I]).DesignWidth;
384 >          end;
385 >
386 >          if (Colsum < ClientWidth) and (ResizeColCount > 0) then
387 >          begin
388 >            adjustment := (ClientWidth - ColSum) div ResizeColCount;
389 >            n := (ClientWidth - ColSum) mod ResizeColCount;
390 >
391 >            for I := 0 to Columns.Count -1 do
392 >              if TDBDynamicGridColumn(Columns[I]).AutoSizeColumn then
393 >              begin
394 >                if I = 0 then
395 >                  Columns[I].Width := Columns[I].Width + adjustment + n
396 >                else
397 >                  Columns[I].Width := Columns[I].Width + adjustment;
398 >              end;
399 >          end;
400 >      end;
401      end;
402      PositionTotals;
403      UpdateEditorPanelBounds;
# Line 374 | Line 409 | end;
409   procedure TDBDynamicGrid.DoEditorHide;
410   begin
411    inherited DoEditorHide;
412 <  if (FExpandedRow >= 0) and (FExpandedRow < RowCount) then
413 <    RowHeights[FExpandedRow] := DefaultRowHeight;
414 <  FExpandedRow := -1;
415 <  if CanFocus then SetFocus;
416 <  if assigned(FOnEditorPanelHide) then
417 <     OnEditorPanelHide(self);
418 <  DoOnResize;
412 >  if Editor = FEditorPanel then
413 >  begin
414 >    if FMouseDown then
415 >      Application.QueueAsyncCall(@PerformEditorHide,FExpandedRow)
416 >    else
417 >      PerformEditorHide(FExpandedRow);
418 >    FExpandedRow := -1;
419 >  end;
420   end;
421  
422   procedure TDBDynamicGrid.DoEditorShow;
423   begin
424 +  if assigned(DataSource) and assigned(DataSource.DataSet) and
425 +             DataSource.DataSet.Active then
426 +  begin
427 +    if (DataSource.DataSet.RecordCount = 0) and (DataSource.DataSet.State <> dsInsert) then
428 +      DataSource.DataSet.Append
429 +  end;
430    if Editor = FEditorPanel then
431    begin
432      if ExpandEditorPanelBelowRow then
# Line 397 | Line 439 | begin
439      FEditorPanel.PerformTab(true);  {Select First Control}
440      if assigned(FOnEditorPanelShow) then
441         OnEditorPanelShow(self);
442 +    if assigned(Editor) and Editor.Visible then
443 +      Editor.SetFocus;
444    end
445    else
446      inherited DoEditorShow;
# Line 461 | Line 505 | begin
505      inherited KeyDown(Key, Shift);
506   end;
507  
508 + function TDBDynamicGrid.ActiveControl: TControl;
509 + var AParent: TWinControl;
510 + begin
511 +  Result := nil;
512 +  AParent := Parent;
513 +  while (AParent <> nil) and  not (AParent is TCustomForm) do
514 +    AParent := AParent.Parent;
515 +  if (AParent <> nil) and (AParent is TCustomForm)then
516 +      Result := TCustomForm(AParent).ActiveControl;
517 + end;
518 +
519   procedure TDBDynamicGrid.DoShowEditorPanel(Data: PtrInt);
520   begin
521    if AppDestroying in Application.Flags then Exit;
# Line 492 | Line 547 | end;
547   procedure TDBDynamicGrid.KeyDownHandler(Sender: TObject; var Key: Word;
548    Shift: TShiftState);
549   var Done: boolean;
550 +    AControl: TControl;
551   begin
552    if Visible and assigned(FEditorPanel) and FEditorPanel.Visible and FWeHaveFocus then
553    begin
554      Done := false;
555 +    AControl := ActiveControl;
556 +    if (AControl <> nil) and (AControl is TCustomComboBox)
557 +                         and ((Key in [VK_UP,VK_DOWN]) or
558 +                         (TCustomComboBox(AControl).DroppedDown and (Key = VK_RETURN)) or
559 +                         ((TCustomComboBox(AControl).Text <> '') and (Key =  VK_ESCAPE))) then
560 +      Exit; {ignore these keys if we are in a  combobox}
561 +
562 +    if (AControl <> nil) and (AControl is TCustomMemo)
563 +                         and (Key in [VK_RETURN,VK_UP,VK_DOWN]) then Exit; {Ignore Return in a CustomMemo}
564 +
565 +    if (AControl <> nil) and (AControl is TCustomGrid)
566 +                         and (Key in [VK_RETURN,VK_UP,VK_DOWN,VK_TAB]) then Exit; {Ignore Return in a CustomMemo}
567 +
568      if assigned(FOnKeyDownHander) then
569        OnKeyDownHander(Sender,Key,Shift,Done);
570      if Done then Exit;
# Line 518 | Line 587 | begin
587    end
588   end;
589  
590 + procedure TDBDynamicGrid.PerformEditorHide(Data: PtrInt);
591 + var ExpandedRow: integer;
592 + begin
593 +  if AppDestroying in Application.Flags then Exit;
594 +  ExpandedRow := integer(Data);
595 +  if (ExpandedRow >= 0) and (ExpandedRow < RowCount) then
596 +    RowHeights[ExpandedRow] := DefaultRowHeight;
597 +  if CanFocus then SetFocus;
598 +  DoOnResize;
599 +  ResetSizes;
600 +  DoOnChangeBounds;
601 +  if assigned(FOnEditorPanelHide) then
602 +     OnEditorPanelHide(self);
603 + end;
604 +
605   procedure TDBDynamicGrid.SetEditorPanel(AValue: TWinControl);
606   begin
607    if FEditorPanel = AValue then Exit;
# Line 552 | Line 636 | begin
636    inherited Loaded;
637    if assigned(FEditorPanel) and not (csDesigning in ComponentState)then
638      FEditorPanel.Visible := false;
639 <  DoGridResize
639 >  if Visible then
640 >    DoGridResize
641   end;
642  
643   procedure TDBDynamicGrid.DoOnResize;
# Line 576 | Line 661 | procedure TDBDynamicGrid.MouseDown(Butto
661    Y: Integer);
662   var Coord: TGridCoord;
663   begin
664 <  inherited MouseDown(Button, Shift, X, Y);
664 >  FMouseDown := true;
665 >  try
666 >    inherited MouseDown(Button, Shift, X, Y);
667 >  finally
668 >    FMouseDown := false;
669 >  end;
670  
671    Coord := MouseCoord(X,Y);
672    if (Coord.X = 0) and (Coord.Y > 0) then
# Line 602 | Line 692 | begin
692    inherited UpdateActive;
693  
694    if not (csLoading in ComponentState) and assigned(DataLink) and
695 +     assigned(FEditorPanel) and not FEditorPanel.Visible and
696       assigned(DataLink.DataSet) and (DataLink.DataSet.State = dsInsert) then
697       Application.QueueAsyncCall(@DoShowEditorPanel,0);
698   end;
# Line 634 | Line 725 | end;
725   procedure TDBDynamicGrid.HideEditorPanel;
726   begin
727    if Editor = FEditorPanel then
728 <    EditorMode := false;
728 >      EditorMode := false;
729   end;
730  
731   procedure TDBDynamicGrid.ShowEditorPanel;
732   begin
733 <  if csDesigning in ComponentState then Exit;
733 >  if (csDesigning in ComponentState) or
734 >   (DataSource = nil) or (DataSource.DataSet = nil)
735 >     or ((DataSource.DataSet.RecordCount = 0) and (DataSource.DataSet.State <> dsInsert)) then
736 >     Exit;
737    Editor := FEditorPanel;
738    EditorMode := true;
739   end;
# Line 698 | Line 792 | procedure TDBLookupCellEditor.CloseUp;
792   begin
793    UpdateData(nil); {Force Record Update}
794    if FGrid<>nil then
795 <    (FGrid as TIBDynamicGrid).EditorTextChanged(FCol, FRow, Text);
795 >  Begin
796 >    (FGrid as TIBDynamicGrid).EditorTextChanged(FCol, FRow, Trim(Text));
797 >    (FGrid as TIBDynamicGrid).UpdateData;
798 >  end;
799    inherited CloseUp;
800   end;
801  
# Line 710 | Line 807 | begin
807      inherited KeyDown(Key, Shift);
808   end;
809  
810 + procedure TDBLookupCellEditor.Loaded;
811 + begin
812 +  inherited Loaded;
813 +  Text := '';
814 + end;
815 +
816   procedure TDBLookupCellEditor.msg_GetValue(var Msg: TGridMessage);
817   begin
818    CheckAndInsert;
# Line 730 | Line 833 | begin
833    FCol := Msg.Col;
834    FRow := Msg.Row;
835    FEditText := Msg.Value;
733  SelStart := Length(Text);
836    TIBDynamicGrid(FGrid).SetupEditor(self,FCol);
837   end;
838  
# Line 779 | Line 881 | begin
881      Editor.OnAutoInsert := OnAutoInsert;
882      Editor.OnCanAutoInsert := OnCanAutoInsert;
883      Editor.OnDrawItem := OnDrawItem;
884 +    Editor.OnCloseUp := OnCloseUp;
885  
886      {Setup Data Links}
887      if KeyField <> '' then
# Line 804 | Line 907 | begin
907          Editor.DataSource := TDBGrid(Grid).DataSource;
908    end;
909    Editor.Text := Editor.FEditText;
910 +  Editor.SelStart := Length(Editor.Text);
911   end;
912  
913   procedure TIBDynamicGridColumn.SetInitialSortColumn(AValue: boolean);
# Line 830 | Line 934 | begin
934    inherited Destroy;
935   end;
936  
833 { TDynamicGridDataLink }
834
835 procedure TDynamicGridDataLink.DataEvent(Event: TDataEvent; Info: Ptrint);
836 begin
837  if (Event = deCheckBrowseMode) and (Info = 1) and not DataSet.Active then
838  begin
839    if (DataSet is TIBDataSet) then
840      FOwner.UpdateSQL(self,TIBDataSet(DataSet).Parser)
841    else
842    if (DataSet is TIBQuery) then
843      FOwner.UpdateSQL(self,TIBQuery(DataSet).Parser)
844  end
845  else
846  inherited DataEvent(Event, Info);
847 end;
848
849 procedure TDynamicGridDataLink.DataSetScrolled(Distance: Integer);
850 begin
851  inherited DataSetScrolled(Distance);
852  FOwner.DataSetScrolled(self)
853 end;
854
855 constructor TDynamicGridDataLink.Create(AOwner: TIBDynamicGrid);
856 begin
857  inherited Create;
858  FOwner := AOwner
859 end;
860
937  
938   { TIBDynamicGrid }
939  
# Line 901 | Line 977 | end;
977   procedure TIBDynamicGrid.SetDataSource(AValue: TDataSource);
978   begin
979    inherited DataSource := AValue;
980 <  FDataLink.DataSource := AValue;
980 >  IBControlLinkChanged;
981   end;
982  
983   procedure TIBDynamicGrid.SetEditorBorderStyle(AValue: TBorderStyle);
# Line 940 | Line 1016 | procedure TIBDynamicGrid.UpdateSQL(Sende
1016   var OrderBy: string;
1017      FieldPosition: integer;
1018   begin
1019 <    if (Sender = TObject(FDataLink)) and assigned(DataSource) and assigned(DataSource.DataSet)
1019 >    if assigned(DataSource) and assigned(DataSource.DataSet)
1020        and (DataSource.DataSet is TIBCustomDataSet) then
1021      begin
1022 +      if (FLastColIndex < 0) or (FLastColIndex >= Columns.Count) then Exit;
1023        FieldPosition := Parser.GetFieldPosition(Columns[FLastColIndex].FieldName);
1024 <      if FieldPosition = 0 then Exit;
1025 <
1026 <      if Descending then
1027 <        Parser.OrderByClause := IntToStr(FieldPosition) + ' desc'
1028 <      else
1029 <        Parser.OrderByClause := IntToStr(FieldPosition) + ' asc';
1024 >      if FieldPosition > 0 then
1025 >      begin
1026 >        if Descending then
1027 >          Parser.OrderByClause := IntToStr(FieldPosition) + ' desc'
1028 >        else
1029 >          Parser.OrderByClause := IntToStr(FieldPosition) + ' asc';
1030 >      end;
1031  
1032        if assigned(FOnUpdateSortOrder) then
1033        begin
# Line 972 | Line 1050 | begin
1050  
1051   end;
1052  
1053 < procedure TIBDynamicGrid.DataSetScrolled(Sender: TObject);
976 < var i: integer;
977 <    F: TField;
1053 > procedure TIBDynamicGrid.RestorePosition;
1054   begin
979    SetLength(FBookmark,FIndexFieldsList.Count);
980    for i := 0 to FIndexFieldsList.Count - 1 do
981    begin
982      F := DataSource.DataSet.FindField(FIndexFieldsList[i]);
983      if assigned(F) then
984         FBookmark[i] := F.AsVariant;
985    end;
986 end;
987
988 procedure TIBDynamicGrid.RestorePosition(Data: PtrInt);
989 begin
990  if AppDestroying in Application.Flags then Exit;
991
1055    if assigned(DataSource) and assigned(DataSource.DataSet) and DataSource.DataSet.Active then
1056    begin
1057 +    if assigned(FOnRestorePosition) then
1058 +      OnRestorePosition(self,@FBookmark);
1059      if (Length(FBookmark) > 0) and
1060        DataSource.DataSet.Locate(FIndexFieldNames,FBookmark,[]) then Exit;
1061  
# Line 999 | Line 1064 | begin
1064    end;
1065   end;
1066  
1067 + procedure TIBDynamicGrid.SavePosition;
1068 + var i: integer;
1069 +    F: TField;
1070 + begin
1071 +  if FIndexFieldsList = nil then Exit;
1072 +
1073 +  SetLength(FBookmark,FIndexFieldsList.Count);
1074 +  for i := 0 to FIndexFieldsList.Count - 1 do
1075 +  begin
1076 +    F := DataSource.DataSet.FindField(FIndexFieldsList[i]);
1077 +    if assigned(F) then
1078 +       FBookmark[i] := F.AsVariant;
1079 +  end;
1080 + end;
1081 +
1082   procedure TIBDynamicGrid.DoReOpen(Data: PtrInt);
1083   begin
1084    DataSource.DataSet.Active := true;
1085   end;
1086  
1087 + procedure TIBDynamicGrid.IBControlLinkChanged;
1088 + begin
1089 +  if (DataSource <> nil) and (DataSource.DataSet <> nil) and (DataSource.DataSet is TIBParserDataSet) then
1090 +    FIBControlLink.IBDataSet := TIBCustomDataSet(DataSource.DataSet)
1091 +  else
1092 +    FIBControlLink.IBDataSet := nil;
1093 + end;
1094 +
1095   procedure TIBDynamicGrid.SetupEditor(aEditor: TDBLookupCellEditor; aCol: integer
1096    );
1097   var C: TIBDynamicGridColumn;
1098   begin
1099    C := ColumnFromGridColumn(aCol) as TIBDynamicGridColumn;
1100 <  C.SetupEditor(aEditor);
1100 >  if (c <> nil) then
1101 >    C.SetupEditor(aEditor);
1102   end;
1103  
1104   procedure TIBDynamicGrid.DoEditorHide;
# Line 1025 | Line 1114 | end;
1114   procedure TIBDynamicGrid.Loaded;
1115   begin
1116    inherited Loaded;
1117 +  IBControlLinkChanged;
1118    ProcessColumns;
1119   end;
1120  
# Line 1054 | Line 1144 | begin
1144    AllowOutboundEvents := false;
1145    try
1146      Coord := MouseCoord(X,Y);
1147 <  if AllowColumnSort and  (Coord.X <> -1) and
1147 >  if AllowColumnSort and  (Coord.X <> -1) and (FixedRows > 0) and
1148     (Coord.Y = 0) and (MouseCoord(X+5,Y).X = Coord.X) {not on boundary}
1149                     and (MouseCoord(X-5,Y).X = Coord.X) then
1150      ColumnHeaderClick(Coord.X-1);
# Line 1063 | Line 1153 | begin
1153    end;
1154   end;
1155  
1156 + procedure TIBDynamicGrid.MoveSelection;
1157 + begin
1158 +  inherited MoveSelection;
1159 +  SavePosition;
1160 + end;
1161 +
1162   procedure TIBDynamicGrid.LinkActive(Value: Boolean);
1163   begin
1164 +  IBControlLinkChanged;
1165    inherited LinkActive(Value);
1166    if (FActive <> Value) and Value then
1167 <    Application.QueueAsyncCall(@RestorePosition,0);
1167 >    RestorePosition;
1168    FActive := Value
1169   end;
1170  
# Line 1076 | Line 1173 | procedure TIBDynamicGrid.Notification(AC
1173   begin
1174    inherited Notification(AComponent, Operation);
1175    if (Operation = opRemove) and
1176 <     (FDataLink <> nil) and (AComponent = DataSource) then DataSource := nil;
1176 >     (FIBControlLink <> nil) and (AComponent = DataSource) then FIBControlLink.IBDataSet := nil;
1177   end;
1178  
1179   procedure TIBDynamicGrid.UpdateActive;
1180   begin
1181    inherited UpdateActive;
1182 <  if assigned(FDataLink) and assigned(FDataLink.DataSet) and
1183 <     FDataLink.DataSet.Active and (FDataLink.DataSet.State = dsInsert) then
1184 <    DataSetScrolled(nil);
1182 >  if assigned(DataLink) and assigned(DataLink.DataSet) and
1183 >     DataLink.DataSet.Active and (DataLink.DataSet.State = dsInsert) then
1184 >   SavePosition;
1185   end;
1186  
1187   constructor TIBDynamicGrid.Create(TheComponent: TComponent);
1188   begin
1189    inherited Create(TheComponent);
1190    FAllowColumnSort := true;
1191 <  FDataLink := TDynamicGridDataLink.Create(self);
1191 >  FIBControlLink := TIBGridControlLink.Create(self);
1192    FIndexFieldsList := TStringList.Create;
1193    FIndexFieldsList.Delimiter := ';';
1194    FIndexFieldsList.StrictDelimiter := true;
# Line 1103 | Line 1200 | end;
1200  
1201   destructor TIBDynamicGrid.Destroy;
1202   begin
1203 <  if assigned(FDataLink) then FDataLink.Free;
1203 >  if assigned(FIBControlLink) then FIBControlLink.Free;
1204    if assigned(FIndexFieldsList) then FIndexFieldsList.Free;
1205    if assigned(FDBLookupCellEditor) then FDBLookupCellEditor.Free;
1206    inherited Destroy;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines