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 29 by tony, Sat May 9 11:37:49 2015 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 31 | Line 31 | interface
31  
32   uses
33    Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, DBGrids, DB,
34 <  IBSqlParser, Grids, IBLookupComboEditBox, LMessages, StdCtrls, ExtCtrls;
34 >  IBSQLParser, Grids, IBLookupComboEditBox, LMessages, StdCtrls, ExtCtrls,
35 >  IBCustomDataSet;
36  
37   type
38    {
# Line 55 | Line 56 | type
56    TOnUpdateSortOrder = procedure (Sender: TObject; ColIndex: integer; var OrderBy: string) of Object;
57    TKeyDownHandler = procedure (Sender: TObject; var Key: Word;  Shift: TShiftState; var Done: boolean) of object;
58  
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
59    { TDBDynamicGridColumn }
60  
61    TDBDynamicGridColumn = class(TColumn)
# Line 162 | Line 151 | end;
151      procedure WndProc(var TheMessage : TLMessage); override;
152      procedure CloseUp; override;
153      procedure KeyDown(var Key : Word; Shift : TShiftState); override;
154 +    procedure Loaded; override;
155      procedure msg_GetValue(var Msg: TGridMessage); message GM_GETVALUE;
156      procedure msg_SetGrid(var Msg: TGridMessage); message GM_SETGRID;
157      procedure msg_SetValue(var Msg: TGridMessage); message GM_SETVALUE;
# Line 219 | Line 209 | end;
209      constructor Create(TheComponent: TComponent); override;
210      destructor Destroy ;override;
211      procedure ResizeColumns;
212 +    property VisibleRowCount;
213    published
214      property EditorPanel: TWinControl read FEditorPanel write SetEditorPanel;
215      property ExpandEditorPanelBelowRow: boolean read FExpandEditorPanelBelowRow write FExpandEditorPanelBelowRow;
# Line 228 | Line 219 | end;
219      property OnKeyDownHander: TKeyDownHandler read FOnKeyDownHander write FOnKeyDownHander;
220   end;
221  
222 +  {TIBGridControlLink}
223 +
224 +  TIBGridControlLink = class(TIBControlLink)
225 +  private
226 +    FOwner: TIBDynamicGrid;
227 +  protected
228 +    procedure UpdateSQL(Sender: TObject); override;
229 +  public
230 +    constructor Create(AOwner: TIBDynamicGrid);
231 +  end;
232 +
233 +  TLocationArray = array of variant;
234 +  PLocationArray = ^TLocationArray;
235 +  TOnRestorePosition = procedure(Sender: TObject; Location: PLocationArray) of object;
236 +
237    { TIBDynamicGrid }
238  
239    TIBDynamicGrid = class(TDBDynamicGrid)
240    private
241      { Private declarations }
242      FAllowColumnSort: boolean;
243 <    FDataLink: TDynamicGridDataLink;
243 >    FIBControlLink: TIBGridControlLink;
244      FOnColumnHeaderClick: TOnColumnHeaderClick;
245 +    FOnRestorePosition: TOnRestorePosition;
246      FOnUpdateSortOrder: TOnUpdateSortOrder;
247      FDefaultPositionAtEnd: boolean;
248      FDescending: boolean;
# Line 243 | Line 250 | end;
250      FLastColIndex: integer;
251      FIndexFieldNames: string;
252      FIndexFieldsList: TStringList;
253 <    FBookmark: array of variant;
253 >    FBookmark: TLocationArray;
254      FDBLookupCellEditor: TDBLookupCellEditor;
255      FActive: boolean;
256      procedure ColumnHeaderClick(Index: integer);
257      function GetDataSource: TDataSource;
258      function GetEditorBorderStyle: TBorderStyle;
259 +    procedure IBControlLinkChanged;
260      procedure SetDataSource(AValue: TDataSource);
261      procedure SetEditorBorderStyle(AValue: TBorderStyle);
262      procedure ProcessColumns;
263      procedure SetIndexFieldNames(AValue: string);
264      procedure UpdateSQL(Sender: TObject; Parser: TSelectSQLParser);
265      procedure UpdateSortColumn(Sender: TObject);
266 <    procedure DataSetScrolled(Sender: TObject);
267 <    procedure RestorePosition(Data: PtrInt);
266 >    procedure RestorePosition;
267 >    procedure SavePosition;
268      procedure DoReOpen(Data: PtrInt);
269      procedure SetupEditor(aEditor: TDBLookupCellEditor; aCol: integer);
270    protected
# Line 266 | Line 274 | end;
274      function  CreateColumns: TGridColumns; override;
275      procedure MouseDown(Button: TMouseButton; Shift:TShiftState; X,Y:Integer); override;
276      procedure LinkActive(Value: Boolean); override;
277 +    procedure MoveSelection; override;
278      procedure Notification(AComponent: TComponent; Operation: TOperation); override;
279      procedure UpdateActive; override;
280    public
# Line 283 | Line 292 | end;
292      property DefaultPositionAtEnd: boolean read  FDefaultPositionAtEnd write FDefaultPositionAtEnd;
293      property IndexFieldNames: string read FIndexFieldNames write SetIndexFieldNames;
294      property OnColumnHeaderClick: TOnColumnHeaderClick read FOnColumnHeaderClick write FOnColumnHeaderClick;
295 +    property OnRestorePosition: TOnRestorePosition read FOnRestorePosition write FOnRestorePosition;
296      property OnUpdateSortOrder: TOnUpdateSortOrder read FOnUpdateSortOrder write FOnUpdateSortOrder;
297   end;
298  
299   implementation
300  
301 < uses Math, IBQuery, IBCustomDataSet, LCLType;
301 > uses Math, IBQuery, LCLType;
302 >
303 > { TIBGridControlLink }
304 >
305 > constructor TIBGridControlLink.Create(AOwner: TIBDynamicGrid);
306 > begin
307 >  inherited Create;
308 >  FOwner := AOwner;
309 > end;
310 >
311 > procedure TIBGridControlLink.UpdateSQL(Sender: TObject);
312 > begin
313 >  FOwner.UpdateSQL(self,TIBParserDataSet(Sender).Parser)
314 > end;
315  
316   { TDBLookupProperties }
317  
# Line 374 | Line 397 | end;
397   procedure TDBDynamicGrid.DoEditorHide;
398   begin
399    inherited DoEditorHide;
400 <  if (FExpandedRow >= 0) and (FExpandedRow < RowCount) then
401 <    RowHeights[FExpandedRow] := DefaultRowHeight;
402 <  FExpandedRow := -1;
403 <  if CanFocus then SetFocus;
404 <  if assigned(FOnEditorPanelHide) then
405 <     OnEditorPanelHide(self);
406 <  DoOnResize;
400 >  if Editor = FEditorPanel then
401 >  begin
402 >    if (FExpandedRow >= 0) and (FExpandedRow < RowCount) then
403 >      RowHeights[FExpandedRow] := DefaultRowHeight;
404 >    FExpandedRow := -1;
405 >    if CanFocus then SetFocus;
406 >    if assigned(FOnEditorPanelHide) then
407 >       OnEditorPanelHide(self);
408 >    DoOnResize;
409 >    ResetSizes;
410 >    DoOnChangeBounds;
411 >  end;
412   end;
413  
414   procedure TDBDynamicGrid.DoEditorShow;
# Line 639 | Line 667 | end;
667  
668   procedure TDBDynamicGrid.ShowEditorPanel;
669   begin
670 <  if csDesigning in ComponentState then Exit;
670 >  if (csDesigning in ComponentState) or
671 >   (DataSource = nil) or (DataSource.DataSet = nil)
672 >     or ((DataSource.DataSet.RecordCount = 0) and (DataSource.DataSet.State <> dsInsert)) then
673 >     Exit;
674    Editor := FEditorPanel;
675    EditorMode := true;
676   end;
# Line 698 | Line 729 | procedure TDBLookupCellEditor.CloseUp;
729   begin
730    UpdateData(nil); {Force Record Update}
731    if FGrid<>nil then
732 <    (FGrid as TIBDynamicGrid).EditorTextChanged(FCol, FRow, Text);
732 >  Begin
733 >    (FGrid as TIBDynamicGrid).EditorTextChanged(FCol, FRow, Trim(Text));
734 >    (FGrid as TIBDynamicGrid).UpdateData;
735 >  end;
736    inherited CloseUp;
737   end;
738  
# Line 710 | Line 744 | begin
744      inherited KeyDown(Key, Shift);
745   end;
746  
747 + procedure TDBLookupCellEditor.Loaded;
748 + begin
749 +  inherited Loaded;
750 +  Text := '';
751 + end;
752 +
753   procedure TDBLookupCellEditor.msg_GetValue(var Msg: TGridMessage);
754   begin
755    CheckAndInsert;
# Line 830 | Line 870 | begin
870    inherited Destroy;
871   end;
872  
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
873  
874   { TIBDynamicGrid }
875  
# Line 901 | Line 913 | end;
913   procedure TIBDynamicGrid.SetDataSource(AValue: TDataSource);
914   begin
915    inherited DataSource := AValue;
916 <  FDataLink.DataSource := AValue;
916 >  IBControlLinkChanged;
917   end;
918  
919   procedure TIBDynamicGrid.SetEditorBorderStyle(AValue: TBorderStyle);
# Line 940 | Line 952 | procedure TIBDynamicGrid.UpdateSQL(Sende
952   var OrderBy: string;
953      FieldPosition: integer;
954   begin
955 <    if (Sender = TObject(FDataLink)) and assigned(DataSource) and assigned(DataSource.DataSet)
955 >    if assigned(DataSource) and assigned(DataSource.DataSet)
956        and (DataSource.DataSet is TIBCustomDataSet) then
957      begin
958 +      if (FLastColIndex < 0) or (FLastColIndex >= Columns.Count) then Exit;
959        FieldPosition := Parser.GetFieldPosition(Columns[FLastColIndex].FieldName);
960        if FieldPosition = 0 then Exit;
961  
# Line 972 | Line 985 | begin
985  
986   end;
987  
988 < procedure TIBDynamicGrid.DataSetScrolled(Sender: TObject);
976 < var i: integer;
977 <    F: TField;
978 < 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);
988 > procedure TIBDynamicGrid.RestorePosition;
989   begin
990  if AppDestroying in Application.Flags then Exit;
991
990    if assigned(DataSource) and assigned(DataSource.DataSet) and DataSource.DataSet.Active then
991    begin
992 +    if assigned(FOnRestorePosition) then
993 +      OnRestorePosition(self,@FBookmark);
994      if (Length(FBookmark) > 0) and
995        DataSource.DataSet.Locate(FIndexFieldNames,FBookmark,[]) then Exit;
996  
# Line 999 | Line 999 | begin
999    end;
1000   end;
1001  
1002 + procedure TIBDynamicGrid.SavePosition;
1003 + var i: integer;
1004 +    F: TField;
1005 + begin
1006 +  if FIndexFieldsList = nil then Exit;
1007 +
1008 +  SetLength(FBookmark,FIndexFieldsList.Count);
1009 +  for i := 0 to FIndexFieldsList.Count - 1 do
1010 +  begin
1011 +    F := DataSource.DataSet.FindField(FIndexFieldsList[i]);
1012 +    if assigned(F) then
1013 +       FBookmark[i] := F.AsVariant;
1014 +  end;
1015 + end;
1016 +
1017   procedure TIBDynamicGrid.DoReOpen(Data: PtrInt);
1018   begin
1019    DataSource.DataSet.Active := true;
1020   end;
1021  
1022 + procedure TIBDynamicGrid.IBControlLinkChanged;
1023 + begin
1024 +  if (DataSource <> nil) and (DataSource.DataSet <> nil) and (DataSource.DataSet is TIBParserDataSet) then
1025 +    FIBControlLink.IBDataSet := TIBCustomDataSet(DataSource.DataSet)
1026 +  else
1027 +    FIBControlLink.IBDataSet := nil;
1028 + end;
1029 +
1030   procedure TIBDynamicGrid.SetupEditor(aEditor: TDBLookupCellEditor; aCol: integer
1031    );
1032   var C: TIBDynamicGridColumn;
1033   begin
1034    C := ColumnFromGridColumn(aCol) as TIBDynamicGridColumn;
1035 <  C.SetupEditor(aEditor);
1035 >  if (c <> nil) then
1036 >    C.SetupEditor(aEditor);
1037   end;
1038  
1039   procedure TIBDynamicGrid.DoEditorHide;
# Line 1025 | Line 1049 | end;
1049   procedure TIBDynamicGrid.Loaded;
1050   begin
1051    inherited Loaded;
1052 +  IBControlLinkChanged;
1053    ProcessColumns;
1054   end;
1055  
# Line 1054 | Line 1079 | begin
1079    AllowOutboundEvents := false;
1080    try
1081      Coord := MouseCoord(X,Y);
1082 <  if AllowColumnSort and  (Coord.X <> -1) and
1082 >  if AllowColumnSort and  (Coord.X <> -1) and (FixedRows > 0) and
1083     (Coord.Y = 0) and (MouseCoord(X+5,Y).X = Coord.X) {not on boundary}
1084                     and (MouseCoord(X-5,Y).X = Coord.X) then
1085      ColumnHeaderClick(Coord.X-1);
# Line 1063 | Line 1088 | begin
1088    end;
1089   end;
1090  
1091 + procedure TIBDynamicGrid.MoveSelection;
1092 + begin
1093 +  inherited MoveSelection;
1094 +  SavePosition;
1095 + end;
1096 +
1097   procedure TIBDynamicGrid.LinkActive(Value: Boolean);
1098   begin
1099 +  IBControlLinkChanged;
1100    inherited LinkActive(Value);
1101    if (FActive <> Value) and Value then
1102 <    Application.QueueAsyncCall(@RestorePosition,0);
1102 >    RestorePosition;
1103    FActive := Value
1104   end;
1105  
# Line 1076 | Line 1108 | procedure TIBDynamicGrid.Notification(AC
1108   begin
1109    inherited Notification(AComponent, Operation);
1110    if (Operation = opRemove) and
1111 <     (FDataLink <> nil) and (AComponent = DataSource) then DataSource := nil;
1111 >     (FIBControlLink <> nil) and (AComponent = DataSource) then FIBControlLink.IBDataSet := nil;
1112   end;
1113  
1114   procedure TIBDynamicGrid.UpdateActive;
1115   begin
1116    inherited UpdateActive;
1117 <  if assigned(FDataLink) and assigned(FDataLink.DataSet) and
1118 <     FDataLink.DataSet.Active and (FDataLink.DataSet.State = dsInsert) then
1119 <    DataSetScrolled(nil);
1117 >  if assigned(DataLink) and assigned(DataLink.DataSet) and
1118 >     DataLink.DataSet.Active and (DataLink.DataSet.State = dsInsert) then
1119 >   SavePosition;
1120   end;
1121  
1122   constructor TIBDynamicGrid.Create(TheComponent: TComponent);
1123   begin
1124    inherited Create(TheComponent);
1125    FAllowColumnSort := true;
1126 <  FDataLink := TDynamicGridDataLink.Create(self);
1126 >  FIBControlLink := TIBGridControlLink.Create(self);
1127    FIndexFieldsList := TStringList.Create;
1128    FIndexFieldsList.Delimiter := ';';
1129    FIndexFieldsList.StrictDelimiter := true;
# Line 1103 | Line 1135 | end;
1135  
1136   destructor TIBDynamicGrid.Destroy;
1137   begin
1138 <  if assigned(FDataLink) then FDataLink.Free;
1138 >  if assigned(FIBControlLink) then FIBControlLink.Free;
1139    if assigned(FIndexFieldsList) then FIndexFieldsList.Free;
1140    if assigned(FDBLookupCellEditor) then FDBLookupCellEditor.Free;
1141    inherited Destroy;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines