ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/public/ibx/trunk/ibcontrols/IBDynamicGrid.pas
Revision: 435
Committed: Mon Jun 3 13:11:42 2024 UTC (3 months, 2 weeks ago) by tony
Content type: text/x-pascal
File size: 39916 byte(s)
Log Message:
Publication of R2-7-0

File Contents

# User Rev Content
1 tony 21 (*
2     * IBX For Lazarus (Firebird Express)
3     *
4     * The contents of this file are subject to the Initial Developer's
5     * Public License Version 1.0 (the "License"); you may not use this
6     * file except in compliance with the License. You may obtain a copy
7     * of the License here:
8     *
9     * http://www.firebirdsql.org/index.php?op=doc&id=idpl
10     *
11     * Software distributed under the License is distributed on an "AS
12     * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
13     * implied. See the License for the specific language governing rights
14     * and limitations under the License.
15     *
16     * The Initial Developer of the Original Code is Tony Whyman.
17     *
18 tony 23 * The Original Code is (C) 2015 Tony Whyman, MWA Software
19 tony 21 * (http://www.mwasoftware.co.uk).
20     *
21     * All Rights Reserved.
22     *
23     * Contributor(s): ______________________________________.
24     *
25     *)
26 tony 35
27 tony 21 unit IBDynamicGrid;
28    
29     {$mode objfpc}{$H+}
30    
31     interface
32    
33     uses
34     Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, DBGrids, DB,
35 tony 435 Grids, IBLookupComboEditBox, LMessages, StdCtrls, ExtCtrls,
36     LCLVersion, IBDynamicInterfaces;
37 tony 21
38     type
39     {
40     TIBDynamicGrid is a TDBGrid descendent that provides for:
41     - automatic resizing of selected columns to fill the available row length
42     - automatic positioning and sizing of a "totals" control, typically at the
43     column footer, on a per column basis.
44 tony 315 - DataSet re-sorting on header row click, sorting the dataset by the selected column.
45 tony 21 A second click on the same header cell reversed the sort order.
46     - Reselection of the same row following resorting.
47     - A new cell editor that provides the same functionality as TIBLookupComboEditBox.
48     Its properties are specified on a per column basis and allows for one or more
49     columns to have their values selected from a list provided by a dataset.
50     Autocomplete and autoinsert are also available. The existing picklist editor
51     is unaffected by the extension.
52     }
53    
54     TIBDynamicGrid = class;
55    
56     TOnColumnHeaderClick = procedure(Sender: TObject; var ColIndex: integer) of object;
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    
60     { TDBDynamicGridColumn }
61    
62     TDBDynamicGridColumn = class(TColumn)
63     private
64     FAutoSizeColumn: boolean;
65     FColumnTotalsControl: TControl;
66     FDesignWidth: integer;
67     function GetWidth: integer;
68     procedure SetWidth(AValue: integer);
69     public
70     property DesignWidth: integer read FDesignWidth;
71     published
72     property ColumnTotalsControl: TControl read FColumnTotalsControl write FColumnTotalsControl;
73     property AutoSizeColumn: boolean read FAutoSizeColumn write FAutoSizeColumn;
74     property Width: integer read GetWidth write SetWidth;
75     end;
76    
77     TIBDynamicGridColumn = class;
78    
79     { TDBLookupProperties }
80    
81     TDBLookupProperties = class(TPersistent)
82     private
83     FAutoComplete: boolean;
84     FAutoCompleteText: TComboBoxAutoCompleteText;
85     FAutoInsert: boolean;
86     FDataFieldName: string;
87     FItemHeight: integer;
88     FItemWidth: integer;
89     FKeyField: string;
90     FKeyPressInterval: integer;
91     FListField: string;
92     FListSource: TDataSource;
93     FOnAutoInsert: TAutoInsert;
94     FOnCanAutoInsert: TCanAutoInsert;
95 tony 31 FOnCloseUp: TNotifyEvent;
96 tony 21 FOnDrawItem: TDrawItemEvent;
97     FOwner: TIBDynamicGridColumn;
98     FRelationName: string;
99     FStyle: TComboBoxStyle;
100     function GetAutoCompleteText: TComboBoxAutoCompleteText;
101     procedure SetAutoCompleteText(AValue: TComboBoxAutoCompleteText);
102     public
103     constructor Create(aOwner: TIBDynamicGridColumn);
104     property Owner: TIBDynamicGridColumn read FOwner;
105     published
106     property DataFieldName: string read FDataFieldName write FDataFieldName;
107     property KeyField: string read FKeyField write FKeyField;
108     property ItemHeight: integer read FItemHeight write FItemHeight;
109     property ItemWidth: integer read FItemWidth write FItemWidth;
110     property ListSource: TDataSource read FListSource write FListSource;
111     property ListField: string read FListField write FListField;
112     property AutoInsert: boolean read FAutoInsert write FAutoInsert default true;
113     property AutoComplete: boolean read FAutoComplete write FAutoComplete default true;
114     property AutoCompleteText: TComboBoxAutoCompleteText
115     read GetAutoCompleteText write SetAutoCompleteText
116     default DefaultComboBoxAutoCompleteText;
117     property KeyPressInterval: integer read FKeyPressInterval write FKeyPressInterval default 500;
118     property RelationName: string read FRelationName write FRelationName;
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 tony 31 property OnCloseUp: TNotifyEvent read FOnCloseUp write FOnCloseUp;
123 tony 21 property OnDrawItem: TDrawItemEvent read FOnDrawItem write FOnDrawItem;
124     end;
125    
126     TDBLookupCellEditor = class;
127    
128     { TIBDynamicGridColumn }
129    
130     TIBDynamicGridColumn = class(TDBDynamicGridColumn)
131     private
132     FDBLookupProperties: TDBLookupProperties;
133     FInitialSortColumn: boolean;
134     procedure DoSetupEditor(Data: PtrInt);
135     procedure DoSetDataSources(Data: PtrInt);
136     procedure SetInitialSortColumn(AValue: boolean);
137     public
138     procedure SetupEditor(Editor: TDBlookupCellEditor);
139     constructor Create(ACollection: TCollection); override;
140     destructor Destroy; override;
141     published
142     property InitialSortColumn: boolean read FInitialSortColumn write SetInitialSortColumn;
143     property DBLookupProperties: TDBLookupProperties read FDBLookupProperties write FDBLookupProperties;
144     end;
145    
146     { TDBLookupCellEditor }
147    
148     TDBLookupCellEditor = class(TIBLookupComboEditBox)
149     private
150     FGrid: TCustomGrid;
151     FCol,FRow: Integer;
152     FEditText: string;
153 tony 39 function EditingKeyField: boolean;
154 tony 21 protected
155     procedure WndProc(var TheMessage : TLMessage); override;
156     procedure CloseUp; override;
157     procedure KeyDown(var Key : Word; Shift : TShiftState); override;
158 tony 27 procedure Loaded; override;
159 tony 21 procedure msg_GetValue(var Msg: TGridMessage); message GM_GETVALUE;
160     procedure msg_SetGrid(var Msg: TGridMessage); message GM_SETGRID;
161     procedure msg_SetValue(var Msg: TGridMessage); message GM_SETVALUE;
162     procedure msg_SetPos(var Msg: TGridMessage); message GM_SETPOS;
163     procedure msg_GetGrid(var Msg: TGridMessage); message GM_GETGRID;
164     public
165     procedure EditingDone; override;
166     property BorderStyle;
167     property OnEditingDone;
168     end;
169    
170 tony 41 TOnSelectPanelEditor = procedure(Sender: TObject; var aEditorPanel: TWinControl) of object;
171    
172 tony 21 TDBDynamicGrid = class(TDBGrid)
173     private
174     { Private declarations }
175     FExpandEditorPanelBelowRow: boolean;
176     FEditorPanel: TWinControl;
177     FExpandedRow: integer;
178     FOnBeforeEditorHide: TNotifyEvent;
179     FOnEditorPanelHide: TNotifyEvent;
180     FOnEditorPanelShow: TNotifyEvent;
181     FOnKeyDownHander: TKeyDownHandler;
182 tony 41 FOnSelectPanelEditor: TOnSelectPanelEditor;
183 tony 21 FResizing: boolean;
184     FWeHaveFocus: boolean;
185 tony 35 FMouseDown: boolean;
186 tony 31 function ActiveControl: TControl;
187 tony 21 procedure DoShowEditorPanel(Data: PtrInt);
188     procedure PositionTotals;
189     procedure KeyDownHandler(Sender: TObject; var Key: Word; Shift: TShiftState);
190 tony 35 procedure PerformEditorHide(Data: PtrInt);
191 tony 21 procedure SetEditorPanel(AValue: TWinControl);
192     protected
193     procedure ChangeBounds(ALeft, ATop, AWidth, AHeight: integer; KeepBase: boolean); override;
194     procedure DoEnter; override;
195     procedure DoExit; override;
196     procedure DoGridResize;
197     procedure DoEditorHide; override;
198     procedure DoEditorShow; override;
199     procedure DrawCellText(aCol,aRow: Integer; aRect: TRect; aState: TGridDrawState; aText: String); override;
200     Function EditingAllowed(ACol : Integer = -1) : Boolean; override;
201     procedure EditorHide; override;
202     procedure IndicatorClicked(Button: TMouseButton; Shift:TShiftState); virtual;
203     procedure KeyDown(var Key : Word; Shift : TShiftState); override;
204     procedure Loaded; override;
205     procedure DoOnResize; override;
206     function CreateColumns: TGridColumns; override;
207     procedure HeaderSized(IsColumn: Boolean; Index: Integer); override;
208     procedure MouseDown(Button: TMouseButton; Shift:TShiftState; X,Y:Integer); override;
209     procedure Notification(AComponent: TComponent; Operation: TOperation); override;
210     procedure TopLeftChanged; override;
211     procedure UpdateActive; override;
212     procedure UpdateEditorPanelBounds;
213     procedure UpdateShowing; override;
214     public
215     procedure HideEditorPanel;
216     procedure ShowEditorPanel;
217     constructor Create(TheComponent: TComponent); override;
218     destructor Destroy ;override;
219     procedure ResizeColumns;
220 tony 27 property VisibleRowCount;
221 tony 21 published
222     property EditorPanel: TWinControl read FEditorPanel write SetEditorPanel;
223     property ExpandEditorPanelBelowRow: boolean read FExpandEditorPanelBelowRow write FExpandEditorPanelBelowRow;
224     property OnBeforeEditorHide: TNotifyEvent read FOnBeforeEditorHide write FOnBeforeEditorHide;
225     property OnEditorPanelShow: TNotifyEvent read FOnEditorPanelShow write FOnEditorPanelShow;
226     property OnEditorPanelHide: TNotifyEvent read FOnEditorPanelHide write FOnEditorPanelHide;
227     property OnKeyDownHander: TKeyDownHandler read FOnKeyDownHander write FOnKeyDownHander;
228 tony 41 property OnSelectPanelEditor: TOnSelectPanelEditor read FOnSelectPanelEditor
229     write FOnSelectPanelEditor;
230 tony 21 end;
231    
232 tony 27 TLocationArray = array of variant;
233     PLocationArray = ^TLocationArray;
234     TOnRestorePosition = procedure(Sender: TObject; Location: PLocationArray) of object;
235    
236 tony 21 { TIBDynamicGrid }
237    
238 tony 435 TIBDynamicGrid = class(TDBDynamicGrid,IDynamicSQLComponent)
239 tony 21 private
240     { Private declarations }
241     FAllowColumnSort: boolean;
242     FOnColumnHeaderClick: TOnColumnHeaderClick;
243 tony 27 FOnRestorePosition: TOnRestorePosition;
244 tony 435 FOnSetParams : TOnSetParams;
245 tony 21 FOnUpdateSortOrder: TOnUpdateSortOrder;
246     FDefaultPositionAtEnd: boolean;
247     FDescending: boolean;
248     FColHeaderClick: boolean;
249     FLastColIndex: integer;
250     FIndexFieldNames: string;
251     FIndexFieldsList: TStringList;
252 tony 27 FBookmark: TLocationArray;
253 tony 21 FDBLookupCellEditor: TDBLookupCellEditor;
254     FActive: boolean;
255 tony 435 FCurDataset: TDataSet; {reference to Dataset on last call to DataSetChanged}
256     FOnUpdateSQL : TOnUpdateSQL;
257 tony 21 procedure ColumnHeaderClick(Index: integer);
258 tony 435 function GetDataSet : TDataSet;
259 tony 21 function GetDataSource: TDataSource;
260     function GetEditorBorderStyle: TBorderStyle;
261 tony 435 procedure DataSetChanged;
262 tony 21 procedure SetDataSource(AValue: TDataSource);
263     procedure SetEditorBorderStyle(AValue: TBorderStyle);
264     procedure ProcessColumns;
265     procedure SetIndexFieldNames(AValue: string);
266     procedure UpdateSortColumn(Sender: TObject);
267 tony 27 procedure RestorePosition;
268     procedure SavePosition;
269 tony 21 procedure DoReOpen(Data: PtrInt);
270     procedure SetupEditor(aEditor: TDBLookupCellEditor; aCol: integer);
271     protected
272     { Protected declarations }
273     procedure DoEditorHide; override;
274     procedure Loaded; override;
275     function CreateColumns: TGridColumns; override;
276     procedure MouseDown(Button: TMouseButton; Shift:TShiftState; X,Y:Integer); override;
277     procedure LinkActive(Value: Boolean); override;
278 tony 27 procedure MoveSelection; override;
279 tony 21 procedure Notification(AComponent: TComponent; Operation: TOperation); override;
280     procedure UpdateActive; override;
281 tony 435 {IDynamicSQLComponent}
282     procedure UpdateSQL(SQLEditor: IDynamicSQLEditor);
283     procedure SetParams(SQLParamProvider: IDynamicSQLParam);
284 tony 21 public
285     { Public declarations }
286     constructor Create(TheComponent: TComponent); override;
287     destructor Destroy; override;
288     function EditorByStyle(Style: TColumnButtonStyle): TWinControl; override;
289     property LastSortColumn: integer read FLastColIndex;
290 tony 435 property DataSet: TDataSet read GetDataSet;
291 tony 21 published
292     { Published declarations }
293     property AllowColumnSort: boolean read FAllowColumnSort write FAllowColumnSort default true;
294     property DataSource: TDataSource read GetDataSource write SetDataSource;
295     property Descending: boolean read FDescending write FDescending;
296     property EditorBorderStyle: TBorderStyle read GetEditorBorderStyle write SetEditorBorderStyle;
297     property DefaultPositionAtEnd: boolean read FDefaultPositionAtEnd write FDefaultPositionAtEnd;
298     property IndexFieldNames: string read FIndexFieldNames write SetIndexFieldNames;
299     property OnColumnHeaderClick: TOnColumnHeaderClick read FOnColumnHeaderClick write FOnColumnHeaderClick;
300 tony 27 property OnRestorePosition: TOnRestorePosition read FOnRestorePosition write FOnRestorePosition;
301 tony 21 property OnUpdateSortOrder: TOnUpdateSortOrder read FOnUpdateSortOrder write FOnUpdateSortOrder;
302 tony 435 property OnUpdateSQL: TOnUpdateSQL read FOnUpdateSQL write FOnUpdateSQL;
303     property OnSetParams: TOnSetParams read FOnSetParams write FOnSetParams;
304 tony 21 end;
305    
306     implementation
307    
308 tony 45 uses LCLType, Variants, EditBtn;
309 tony 21
310     { TDBLookupProperties }
311    
312     function TDBLookupProperties.GetAutoCompleteText: TComboBoxAutoCompleteText;
313     begin
314     Result := FAutoCompleteText;
315     if AutoComplete then
316     Result := Result + [cbactEnabled]
317     end;
318    
319     procedure TDBLookupProperties.SetAutoCompleteText(
320     AValue: TComboBoxAutoCompleteText);
321     begin
322     if AValue <> AutoCompleteText then
323     begin
324     FAutoComplete := cbactEnabled in AValue;
325     FAutoCompleteText := AValue - [cbactEnabled]
326     end;
327     end;
328    
329     constructor TDBLookupProperties.Create(aOwner: TIBDynamicGridColumn);
330     begin
331     inherited Create;
332     FOwner := aOwner;
333     FAutoInsert := true;
334     FAutoComplete := true;
335     FAutoCompleteText := DefaultComboBoxAutoCompleteText;
336     FKeyPressInterval := 500;
337     FListSource := nil;
338     FStyle := csDropDown;
339     end;
340    
341     { TDBDynamicGrid }
342    
343     procedure TDBDynamicGrid.DoGridResize;
344     var ColSum: integer;
345     ResizeColCount: integer;
346     I: integer;
347     adjustment: integer;
348     n: integer;
349     begin
350     if (csDesigning in ComponentState) or (Columns.Count = 0) then Exit;
351    
352     FResizing := true;
353     try
354     ColSum := 0;
355    
356 tony 35 if (ColCount = 1) and TDBDynamicGridColumn(Columns[0]).AutoSizeColumn then
357     Columns[0].Width := ClientWidth
358     else
359 tony 21 begin
360 tony 35 for I := 0 to ColCount - 1 do
361 tony 39 if (I < FixedCols) or Columns[I - FixedCols].Visible then
362 tony 35 ColSum := ColSum + ColWidths[I];
363 tony 21
364 tony 35 if Colsum <> ClientWidth then
365     begin
366     ResizeColCount := 0;
367     for I := 0 to Columns.Count -1 do
368 tony 39 if TDBDynamicGridColumn(Columns[I]).AutoSizeColumn and Columns[I].Visible then
369 tony 35 begin
370     Inc(ResizeColCount);
371     Colsum := Colsum + TDBDynamicGridColumn(Columns[I]).DesignWidth - Columns[I].Width;
372     Columns[I].Width := TDBDynamicGridColumn(Columns[I]).DesignWidth;
373     end;
374 tony 21
375 tony 35 if (Colsum < ClientWidth) and (ResizeColCount > 0) then
376     begin
377     adjustment := (ClientWidth - ColSum) div ResizeColCount;
378     n := (ClientWidth - ColSum) mod ResizeColCount;
379    
380     for I := 0 to Columns.Count -1 do
381 tony 39 if TDBDynamicGridColumn(Columns[I]).AutoSizeColumn and Columns[I].Visible then
382 tony 35 begin
383     if I = 0 then
384     Columns[I].Width := Columns[I].Width + adjustment + n
385     else
386     Columns[I].Width := Columns[I].Width + adjustment;
387     end;
388     end;
389     end;
390 tony 21 end;
391     PositionTotals;
392     UpdateEditorPanelBounds;
393     finally
394     FResizing := false
395     end;
396     end;
397    
398     procedure TDBDynamicGrid.DoEditorHide;
399     begin
400     inherited DoEditorHide;
401 tony 27 if Editor = FEditorPanel then
402     begin
403 tony 35 if FMouseDown then
404     Application.QueueAsyncCall(@PerformEditorHide,FExpandedRow)
405     else
406     PerformEditorHide(FExpandedRow);
407 tony 27 FExpandedRow := -1;
408     end;
409 tony 21 end;
410    
411     procedure TDBDynamicGrid.DoEditorShow;
412     begin
413 tony 35 if assigned(DataSource) and assigned(DataSource.DataSet) and
414     DataSource.DataSet.Active then
415     begin
416     if (DataSource.DataSet.RecordCount = 0) and (DataSource.DataSet.State <> dsInsert) then
417     DataSource.DataSet.Append
418     end;
419 tony 21 if Editor = FEditorPanel then
420     begin
421     if ExpandEditorPanelBelowRow then
422     RowHeights[Row] := FEditorPanel.Height + DefaultRowHeight
423     else
424     RowHeights[Row] := FEditorPanel.Height;
425     FExpandedRow := Row;
426     inherited DoEditorShow;
427     UpdateEditorPanelBounds; {Position Editor Panel over expanded Row}
428     FEditorPanel.PerformTab(true); {Select First Control}
429     if assigned(FOnEditorPanelShow) then
430     OnEditorPanelShow(self);
431 tony 35 if assigned(Editor) and Editor.Visible then
432     Editor.SetFocus;
433 tony 21 end
434     else
435     inherited DoEditorShow;
436     end;
437    
438     procedure TDBDynamicGrid.DrawCellText(aCol, aRow: Integer; aRect: TRect;
439     aState: TGridDrawState; aText: String);
440     var Style: TTextStyle;
441     OldStyle: TTextStyle;
442     begin
443     if ExpandEditorPanelBelowRow and assigned(FEditorPanel) and FEditorPanel.Visible and (aRow = FExpandedRow) then
444     begin
445     {Draw the text at the top of the cell}
446     Style := Canvas.TextStyle;
447     OldStyle := Style;
448     try
449     Style.Layout := tlTop;
450     Canvas.TextStyle := Style;
451     inherited DrawCellText(aCol, aRow, aRect, aState, aText);
452     finally
453     Canvas.TextStyle := OldStyle;
454     end;
455    
456     end
457     else
458     inherited DrawCellText(aCol, aRow, aRect, aState, aText);
459     end;
460    
461     function TDBDynamicGrid.EditingAllowed(ACol: Integer): Boolean;
462     begin
463     Result := ((FEditorPanel <> nil) and (FEditorPanel = Editor))
464     or inherited EditingAllowed(ACol);
465     end;
466    
467     procedure TDBDynamicGrid.EditorHide;
468     begin
469     if assigned(FOnBeforeEditorHide) then
470     OnBeforeEditorHide(self);
471     inherited EditorHide;
472     end;
473    
474     procedure TDBDynamicGrid.IndicatorClicked(Button: TMouseButton;
475     Shift: TShiftState);
476     begin
477     if assigned(FEditorPanel) then
478     begin
479     if FEditorPanel.Visible then
480     HideEditorPanel
481     else
482     ShowEditorPanel;
483     end;
484     end;
485    
486     procedure TDBDynamicGrid.KeyDown(var Key: Word; Shift: TShiftState);
487     begin
488     if (Key = VK_F2) and (Shift = []) and assigned(FEditorPanel) then
489     begin
490     if not FEditorPanel.Visible then
491     ShowEditorPanel
492     end
493     else
494     inherited KeyDown(Key, Shift);
495     end;
496    
497 tony 31 function TDBDynamicGrid.ActiveControl: TControl;
498     var AParent: TWinControl;
499     begin
500     Result := nil;
501     AParent := Parent;
502     while (AParent <> nil) and not (AParent is TCustomForm) do
503     AParent := AParent.Parent;
504     if (AParent <> nil) and (AParent is TCustomForm)then
505     Result := TCustomForm(AParent).ActiveControl;
506     end;
507    
508 tony 21 procedure TDBDynamicGrid.DoShowEditorPanel(Data: PtrInt);
509     begin
510     if AppDestroying in Application.Flags then Exit;
511     ShowEditorPanel;
512     end;
513    
514     procedure TDBDynamicGrid.PositionTotals;
515     var I: integer;
516     acol: TDBDynamicGridColumn;
517     LPos: integer;
518     begin
519     LPos := Left;
520     for I := 0 to FirstGridColumn - 1 do
521     LPos := LPos + ColWidths[I];
522    
523     for I := 0 to Columns.Count - 1 do
524     begin
525     acol := TDBDynamicGridColumn(Columns[I]);
526     if assigned(acol.FColumnTotalsControl) then
527     begin
528     acol.FColumnTotalsControl.AutoSize := false;
529     acol.FColumnTotalsControl.Left := LPos;
530     acol.FColumnTotalsControl.Width := acol.Width
531     end;
532     LPos := LPos + acol.Width;
533     end;
534     end;
535    
536     procedure TDBDynamicGrid.KeyDownHandler(Sender: TObject; var Key: Word;
537     Shift: TShiftState);
538     var Done: boolean;
539 tony 31 AControl: TControl;
540 tony 21 begin
541     if Visible and assigned(FEditorPanel) and FEditorPanel.Visible and FWeHaveFocus then
542     begin
543     Done := false;
544 tony 31 AControl := ActiveControl;
545     if (AControl <> nil) and (AControl is TCustomComboBox)
546     and ((Key in [VK_UP,VK_DOWN]) or
547     (TCustomComboBox(AControl).DroppedDown and (Key = VK_RETURN)) or
548     ((TCustomComboBox(AControl).Text <> '') and (Key = VK_ESCAPE))) then
549     Exit; {ignore these keys if we are in a combobox}
550    
551     if (AControl <> nil) and (AControl is TCustomMemo)
552 tony 49 and (Key in [VK_RETURN,VK_UP,VK_DOWN]) then Exit; {Ignore keys in a CustomMemo}
553 tony 35
554     if (AControl <> nil) and (AControl is TCustomGrid)
555 tony 49 and (Key in [VK_RETURN,VK_UP,VK_DOWN,VK_TAB]) then Exit; {Ignore keys in a Custom Grid}
556 tony 35
557 tony 49 if (AControl <> nil) and (AControl is TEBEdit) and (AControl.Owner is TDateEdit) then
558     begin
559     if (Key in [VK_LEFT,VK_RIGHT]) then Exit; {Ignore navigation keys}
560     if TDateEdit(AControl.Owner).DroppedDown and
561     (Key in [VK_RETURN,VK_UP,VK_DOWN,VK_ESCAPE]) then Exit; {Ignore TCalender navigation keys in a Data edit}
562     end;
563 tony 45
564 tony 21 if assigned(FOnKeyDownHander) then
565     OnKeyDownHander(Sender,Key,Shift,Done);
566     if Done then Exit;
567    
568     {Allow Scrolling}
569     if Key in [VK_UP,VK_DOWN] then
570     KeyDown(Key,Shift)
571     else
572     {Cancel Editor}
573     if Key = VK_ESCAPE then
574     begin
575     if DataLink.DataSet.State in [dsInsert,dsEdit] then
576     DataLink.DataSet.Cancel;
577     KeyDown(Key,Shift);
578     end
579     {save}
580     else
581     if Key = VK_F2 then
582     HideEditorPanel;
583     end
584     end;
585    
586 tony 35 procedure TDBDynamicGrid.PerformEditorHide(Data: PtrInt);
587     var ExpandedRow: integer;
588     begin
589     if AppDestroying in Application.Flags then Exit;
590     ExpandedRow := integer(Data);
591     if (ExpandedRow >= 0) and (ExpandedRow < RowCount) then
592     RowHeights[ExpandedRow] := DefaultRowHeight;
593     if CanFocus then SetFocus;
594     DoOnResize;
595     ResetSizes;
596     DoOnChangeBounds;
597     if assigned(FOnEditorPanelHide) then
598     OnEditorPanelHide(self);
599     end;
600    
601 tony 21 procedure TDBDynamicGrid.SetEditorPanel(AValue: TWinControl);
602     begin
603     if FEditorPanel = AValue then Exit;
604     if FEditorPanel <> nil then
605     RemoveFreeNotification(FEditorPanel);
606     FEditorPanel := AValue;
607 tony 39 if FEditorPanel <> nil then
608     FreeNotification(FEditorPanel);
609 tony 21 end;
610    
611     procedure TDBDynamicGrid.ChangeBounds(ALeft, ATop, AWidth, AHeight: integer;
612     KeepBase: boolean);
613     begin
614     if assigned(FEditorPanel) and FEditorPanel.Visible then
615     Application.QueueAsyncCall(@DoShowEditorPanel,0); {Restore afterwards if necessary}
616     inherited ChangeBounds(ALeft, ATop, AWidth, AHeight, KeepBase);
617     end;
618    
619     procedure TDBDynamicGrid.DoEnter;
620     begin
621     inherited DoEnter;
622     FWeHaveFocus := true;
623     end;
624    
625     procedure TDBDynamicGrid.DoExit;
626     begin
627     FWeHaveFocus := false;
628     inherited DoExit;
629     end;
630    
631     procedure TDBDynamicGrid.Loaded;
632     begin
633     inherited Loaded;
634     if assigned(FEditorPanel) and not (csDesigning in ComponentState)then
635     FEditorPanel.Visible := false;
636 tony 35 if Visible then
637     DoGridResize
638 tony 21 end;
639    
640     procedure TDBDynamicGrid.DoOnResize;
641     begin
642     inherited DoOnResize;
643     DoGridResize
644     end;
645    
646     function TDBDynamicGrid.CreateColumns: TGridColumns;
647     begin
648     result := TDBGridColumns.Create(Self, TDBDynamicGridColumn);
649     end;
650    
651     procedure TDBDynamicGrid.HeaderSized(IsColumn: Boolean; Index: Integer);
652     begin
653     inherited HeaderSized(IsColumn, Index);
654     PositionTotals
655     end;
656    
657     procedure TDBDynamicGrid.MouseDown(Button: TMouseButton; Shift: TShiftState; X,
658     Y: Integer);
659     var Coord: TGridCoord;
660     begin
661 tony 35 FMouseDown := true;
662     try
663     inherited MouseDown(Button, Shift, X, Y);
664     finally
665     FMouseDown := false;
666     end;
667 tony 21
668     Coord := MouseCoord(X,Y);
669     if (Coord.X = 0) and (Coord.Y > 0) then
670     IndicatorClicked(Button,Shift);
671     end;
672    
673     procedure TDBDynamicGrid.Notification(AComponent: TComponent;
674     Operation: TOperation);
675 tony 39 var i: integer;
676 tony 21 begin
677     inherited Notification(AComponent, Operation);
678 tony 39 if (Operation = opRemove) and not (csDestroying in ComponentState) then
679     begin
680     if AComponent = FEditorPanel then
681     FEditorPanel := nil
682     else
683     if AComponent is TControl then
684     begin
685     for i := 0 to Columns.Count - 1 do
686     if TDBDynamicGridColumn(Columns[I]).ColumnTotalsControl = AComponent then
687     TDBDynamicGridColumn(Columns[I]).ColumnTotalsControl := nil;
688     end;
689     end
690 tony 21 end;
691    
692     procedure TDBDynamicGrid.TopLeftChanged;
693     begin
694     inherited TopLeftChanged;
695     UpdateEditorPanelBounds;
696     end;
697    
698     procedure TDBDynamicGrid.UpdateActive;
699     begin
700     inherited UpdateActive;
701    
702 tony 41 if not (csLoading in ComponentState) and assigned(DataLink)
703     and assigned(DataLink.DataSet) and DataLink.DataSet.Active then
704     DoGridResize;
705    
706 tony 21 if not (csLoading in ComponentState) and assigned(DataLink) and
707 tony 35 assigned(FEditorPanel) and not FEditorPanel.Visible and
708 tony 21 assigned(DataLink.DataSet) and (DataLink.DataSet.State = dsInsert) then
709     Application.QueueAsyncCall(@DoShowEditorPanel,0);
710     end;
711    
712     procedure TDBDynamicGrid.UpdateEditorPanelBounds;
713     var R: TRect;
714     Dummy: integer;
715     begin
716     if assigned(FEditorPanel) and FEditorPanel.Visible and
717     (FExpandedRow >= 0) and (FExpandedRow < RowCount) then
718     begin
719     // Upper and Lower bounds for this row
720     ColRowToOffSet(False, True, FExpandedRow, R.Top, R.Bottom);
721     //Left Bound for visible Columns
722     ColRowToOffSet(True,True,1,R.Left,Dummy);
723     //Right Bound for visible columns
724     ColRowToOffSet(True,True,ColCount - 1,Dummy,R.Right);
725     if ExpandEditorPanelBelowRow then
726     R.Top := R.Top + DefaultRowHeight;
727     FEditorPanel.BoundsRect := R;
728     end;
729     end;
730    
731     procedure TDBDynamicGrid.UpdateShowing;
732     begin
733     inherited UpdateShowing;
734     DoGridResize
735     end;
736    
737     procedure TDBDynamicGrid.HideEditorPanel;
738     begin
739     if Editor = FEditorPanel then
740 tony 35 EditorMode := false;
741 tony 21 end;
742    
743     procedure TDBDynamicGrid.ShowEditorPanel;
744 tony 41 var aEditor: TWinControl;
745 tony 21 begin
746 tony 27 if (csDesigning in ComponentState) or
747     (DataSource = nil) or (DataSource.DataSet = nil)
748     or ((DataSource.DataSet.RecordCount = 0) and (DataSource.DataSet.State <> dsInsert)) then
749     Exit;
750 tony 41 aEditor := FEditorPanel;
751     if assigned(FOnSelectPanelEditor) then
752     OnSelectPanelEditor(self,aEditor);
753     if FEditorPanel <> aEditor then
754     SetEditorPanel(aEditor);
755     Editor := aEditor;
756 tony 21 EditorMode := true;
757     end;
758    
759     constructor TDBDynamicGrid.Create(TheComponent: TComponent);
760     begin
761     inherited Create(TheComponent);
762     ScrollBars := ssAutoVertical;
763     if not (csDesigning in ComponentState) then
764     Application.AddOnKeyDownBeforeHandler(@KeyDownHandler,false);
765     end;
766    
767     destructor TDBDynamicGrid.Destroy;
768     begin
769     if not (csDesigning in ComponentState) then
770     Application.RemoveOnKeyDownBeforeHandler(@KeyDownHandler);
771     inherited Destroy;
772     end;
773    
774     procedure TDBDynamicGrid.ResizeColumns;
775     begin
776     DoGridResize;
777     end;
778    
779     { TDBDynamicGridColumn }
780    
781     procedure TDBDynamicGridColumn.SetWidth(AValue: integer);
782     begin
783     if Width = AValue then Exit;
784     inherited Width := AValue;
785     if not TDBDynamicGrid(Grid).FResizing then
786     FDesignWidth := Width
787     end;
788    
789     function TDBDynamicGridColumn.GetWidth: integer;
790     begin
791     Result := inherited Width
792     end;
793    
794 tony 39 type
795     THackedGrid = class(TIBDynamicGrid)
796     public
797     property FixedCols;
798     end;
799    
800 tony 21 { TDBLookupCellEditor }
801    
802 tony 39 function TDBLookupCellEditor.EditingKeyField: boolean;
803     begin
804     with TIBDynamicGridColumn(TDBGrid(FGrid).Columns[FCol - THackedGrid(FGrid).FixedCols]) do
805     Result := CompareText(FieldName, DBLookupProperties.DataFieldName) = 0;
806     end;
807    
808 tony 21 procedure TDBLookupCellEditor.WndProc(var TheMessage: TLMessage);
809     begin
810     if TheMessage.msg=LM_KILLFOCUS then begin
811     if HWND(TheMessage.WParam) = HWND(Handle) then begin
812     // lost the focus but it returns to ourselves
813     // eat the message.
814     TheMessage.Result := 0;
815     exit;
816     end;
817     end;
818     inherited WndProc(TheMessage);
819     end;
820    
821     procedure TDBLookupCellEditor.CloseUp;
822     begin
823     UpdateData(nil); {Force Record Update}
824     if FGrid<>nil then
825 tony 27 Begin
826 tony 39 if EditingKeyField then
827     begin
828     if not VarIsNull(KeyValue) then
829     (FGrid as TIBDynamicGrid).EditorTextChanged(FCol, FRow, KeyValue)
830     end
831     else
832     (FGrid as TIBDynamicGrid).EditorTextChanged(FCol, FRow, Trim(Text));
833 tony 27 (FGrid as TIBDynamicGrid).UpdateData;
834     end;
835 tony 21 inherited CloseUp;
836     end;
837    
838     procedure TDBLookupCellEditor.KeyDown(var Key: Word; Shift: TShiftState);
839     begin
840     if (Key = VK_TAB) and assigned(FGrid) then
841     TIBDynamicGrid(FGrid).KeyDown(Key,Shift)
842     else
843     inherited KeyDown(Key, Shift);
844     end;
845    
846 tony 27 procedure TDBLookupCellEditor.Loaded;
847     begin
848     inherited Loaded;
849     Text := '';
850     end;
851    
852 tony 21 procedure TDBLookupCellEditor.msg_GetValue(var Msg: TGridMessage);
853     begin
854     CheckAndInsert;
855     Msg.Col := FCol;
856     Msg.Row := FRow;
857 tony 39 if EditingKeyField then
858     begin
859     if not VarIsNull(KeyValue) then
860     Msg.Value:= KeyValue
861     else
862     Msg.Value:= ''
863     end
864     else
865     Msg.Value:= Trim(Text);
866 tony 21 end;
867    
868     procedure TDBLookupCellEditor.msg_SetGrid(var Msg: TGridMessage);
869     begin
870     FGrid:=Msg.Grid;
871     Msg.Options:=EO_AUTOSIZE or EO_SELECTALL or EO_HOOKKEYPRESS or EO_HOOKKEYUP;
872     end;
873    
874     procedure TDBLookupCellEditor.msg_SetValue(var Msg: TGridMessage);
875     begin
876     FGrid := Msg.Grid;
877     FCol := Msg.Col;
878     FRow := Msg.Row;
879     FEditText := Msg.Value;
880     TIBDynamicGrid(FGrid).SetupEditor(self,FCol);
881     end;
882    
883     procedure TDBLookupCellEditor.msg_SetPos(var Msg: TGridMessage);
884     begin
885     FCol := Msg.Col;
886     FRow := Msg.Row;
887     end;
888    
889     procedure TDBLookupCellEditor.msg_GetGrid(var Msg: TGridMessage);
890     begin
891     Msg.Grid := FGrid;
892     Msg.Options:= EO_IMPLEMENTED;
893     end;
894    
895     procedure TDBLookupCellEditor.EditingDone;
896     begin
897     inherited EditingDone;
898     if FGrid<>nil then
899     FGrid.EditingDone;
900     end;
901    
902     { TIBDynamicGridColumn }
903    
904     procedure TIBDynamicGridColumn.DoSetupEditor(Data: PtrInt);
905     var Editor: TDBlookupCellEditor;
906     begin
907     if AppDestroying in Application.Flags then Exit;
908    
909     Editor := TDBlookupCellEditor(Data);
910     Editor.DataSource := nil;
911     Editor.ListSource := nil; {Allows change without causing an error}
912     Editor.KeyValue := NULL;
913    
914     with DBLookupProperties do
915     begin
916     {Setup Properties}
917     Editor.AutoInsert := AutoInsert;
918     Editor.AutoComplete := AutoComplete;
919     Editor.AutoCompleteText := AutoCompleteText;
920     Editor.KeyPressInterval := KeyPressInterval;
921     Editor.Style := Style;
922     Editor.ItemHeight := ItemHeight;
923     Editor.ItemWidth := ItemWidth;
924     Editor.RelationName := RelationName;
925     Editor.OnAutoInsert := OnAutoInsert;
926     Editor.OnCanAutoInsert := OnCanAutoInsert;
927     Editor.OnDrawItem := OnDrawItem;
928 tony 31 Editor.OnCloseUp := OnCloseUp;
929 tony 21
930     {Setup Data Links}
931     if KeyField <> '' then
932     Editor.KeyField := KeyField
933     else
934     Editor.KeyField := ListField;
935     Editor.ListField := ListField;
936     Editor.DataField := DataFieldName;
937     end;
938     Application.QueueAsyncCall(@DoSetDataSources,PtrInt(Editor));
939     end;
940    
941     procedure TIBDynamicGridColumn.DoSetDataSources(Data: PtrInt);
942     var Editor: TDBlookupCellEditor;
943     begin
944     if AppDestroying in Application.Flags then Exit;
945    
946     Editor := TDBlookupCellEditor(Data);
947     with DBLookupProperties do
948     begin
949     Editor.ListSource := ListSource;
950     if DataFieldName <> '' then
951     Editor.DataSource := TDBGrid(Grid).DataSource;
952     end;
953 tony 39 if Editor.EditingKeyField then
954     begin
955     if not Field.IsNull then
956     Editor.KeyValue := Editor.FEditText
957     end
958     else
959     Editor.Text := Editor.FEditText;
960 tony 31 Editor.SelStart := Length(Editor.Text);
961 tony 21 end;
962    
963     procedure TIBDynamicGridColumn.SetInitialSortColumn(AValue: boolean);
964     begin
965     if FInitialSortColumn = AValue then Exit;
966     FInitialSortColumn := AValue;
967     (Grid as TIBDynamicGrid).UpdateSortColumn(self)
968     end;
969    
970     procedure TIBDynamicGridColumn.SetupEditor(Editor: TDBlookupCellEditor);
971     begin
972     Application.QueueAsyncCall(@DoSetupEditor,PtrInt(Editor));
973     end;
974    
975     constructor TIBDynamicGridColumn.Create(ACollection: TCollection);
976     begin
977     inherited Create(ACollection);
978     FDBLookupProperties := TDBLookupProperties.Create(self);
979     end;
980    
981     destructor TIBDynamicGridColumn.Destroy;
982     begin
983     if assigned(FDBLookupProperties) then FDBLookupProperties.Free;
984 tony 80 Application.RemoveAsyncCalls(self);
985 tony 21 inherited Destroy;
986     end;
987    
988    
989     { TIBDynamicGrid }
990    
991     procedure TIBDynamicGrid.ColumnHeaderClick(Index: integer);
992     begin
993     FColHeaderClick := true;
994     try
995     if Index = FLastColIndex then
996     FDescending := not FDescending;
997    
998     if assigned(FOnColumnHeaderClick) then
999     OnColumnHeaderClick(self,Index);
1000    
1001     FLastColIndex := Index;
1002 tony 435 if assigned(DataSource) and assigned(DataSource.DataSet) and DataSource.DataSet.Active then
1003 tony 21 begin
1004 tony 37 if FLastColIndex < Columns.Count then
1005     {try and cache field position while dataset still open}
1006 tony 21 DataSource.DataSet.Active := false;
1007     Application.QueueAsyncCall(@DoReopen,0)
1008     end;
1009     finally
1010     FColHeaderClick := false
1011     end;
1012     end;
1013    
1014 tony 435 function TIBDynamicGrid.GetDataSet : TDataSet;
1015     begin
1016     if DataSource <> nil then
1017     Result := DataSource.Dataset
1018     else
1019     Result := nil;
1020     end;
1021    
1022 tony 21 function TIBDynamicGrid.GetDataSource: TDataSource;
1023     begin
1024     if assigned(DataLink) then
1025     Result := inherited DataSource
1026     else
1027     Result := nil;
1028     end;
1029    
1030     function TIBDynamicGrid.GetEditorBorderStyle: TBorderStyle;
1031     begin
1032     if Editor = FDBLookupCellEditor then
1033     Result := FDBLookupCellEditor.BorderStyle
1034     else
1035     Result := inherited EditorBorderStyle
1036     end;
1037    
1038     procedure TIBDynamicGrid.SetDataSource(AValue: TDataSource);
1039     begin
1040     inherited DataSource := AValue;
1041 tony 435 DataSetChanged;
1042 tony 21 end;
1043    
1044     procedure TIBDynamicGrid.SetEditorBorderStyle(AValue: TBorderStyle);
1045     begin
1046     inherited EditorBorderStyle := AValue;
1047     if FDBLookupCellEditor.BorderStyle <> AValue then
1048     begin
1049     FDBLookupCellEditor.BorderStyle := AValue;
1050     if (Editor = FDBLookupCellEditor) and EditorMode then
1051     EditorWidthChanged(Col,FDBLookupCellEditor.Width);
1052     end;
1053     end;
1054    
1055     procedure TIBDynamicGrid.ProcessColumns;
1056     var i: integer;
1057     begin
1058     for i := 0 to Columns.Count - 1 do
1059     begin
1060     if TIBDynamicGridColumn(columns[i]).InitialSortColumn then
1061     FLastColIndex := i
1062     end
1063     end;
1064    
1065     procedure TIBDynamicGrid.SetIndexFieldNames(AValue: string);
1066     var idx: integer;
1067     begin
1068     if FIndexFieldNames = AValue then Exit;
1069     FIndexFieldNames := AValue;
1070     idx := 1;
1071     FIndexFieldsList.Clear;
1072     while idx <= Length(AValue) do
1073     FIndexFieldsList.Add(ExtractFieldName(AValue,idx));
1074     end;
1075    
1076     procedure TIBDynamicGrid.UpdateSortColumn(Sender: TObject);
1077     var i: integer;
1078     begin
1079     if Sender is TIBDynamicGridColumn then
1080     begin
1081     for i := 0 to Columns.Count -1 do
1082     if TObject(Columns[i]) <> Sender then
1083     TIBDynamicGridColumn(Columns[i]).InitialSortColumn := false
1084     end
1085    
1086     end;
1087    
1088 tony 27 procedure TIBDynamicGrid.RestorePosition;
1089 tony 21 begin
1090     if assigned(DataSource) and assigned(DataSource.DataSet) and DataSource.DataSet.Active then
1091     begin
1092 tony 27 if assigned(FOnRestorePosition) then
1093     OnRestorePosition(self,@FBookmark);
1094 tony 21 if (Length(FBookmark) > 0) and
1095     DataSource.DataSet.Locate(FIndexFieldNames,FBookmark,[]) then Exit;
1096    
1097     if FDefaultPositionAtEnd then
1098     DataSource.DataSet.Last
1099     end;
1100     end;
1101    
1102 tony 27 procedure TIBDynamicGrid.SavePosition;
1103     var i: integer;
1104     F: TField;
1105     begin
1106     if FIndexFieldsList = nil then Exit;
1107    
1108     SetLength(FBookmark,FIndexFieldsList.Count);
1109     for i := 0 to FIndexFieldsList.Count - 1 do
1110     begin
1111     F := DataSource.DataSet.FindField(FIndexFieldsList[i]);
1112     if assigned(F) then
1113     FBookmark[i] := F.AsVariant;
1114     end;
1115     end;
1116    
1117 tony 21 procedure TIBDynamicGrid.DoReOpen(Data: PtrInt);
1118     begin
1119     DataSource.DataSet.Active := true;
1120     end;
1121    
1122 tony 435 procedure TIBDynamicGrid.DataSetChanged;
1123 tony 27 begin
1124 tony 435 if FCurDataset <> DataSet then
1125     begin
1126     if (FCurDataset <> nil) and (FCurDataset is IDynamicSQLDataset) then
1127     (FCurDataset as IDynamicSQLDataset).UnRegisterDynamicComponent(self);
1128     if (Dataset <> nil) and (DataSet is IDynamicSQLDataset) then
1129     begin
1130     with DataSet as IDynamicSQLDataset do
1131     if dcChangeDatasetOrder in GetCapabilities then
1132     RegisterDynamicComponent(self)
1133     end;
1134     FCurDataset := DataSet;
1135     end;
1136 tony 27 end;
1137    
1138 tony 21 procedure TIBDynamicGrid.SetupEditor(aEditor: TDBLookupCellEditor; aCol: integer
1139     );
1140     var C: TIBDynamicGridColumn;
1141     begin
1142     C := ColumnFromGridColumn(aCol) as TIBDynamicGridColumn;
1143 tony 27 if (c <> nil) then
1144     C.SetupEditor(aEditor);
1145 tony 21 end;
1146    
1147     procedure TIBDynamicGrid.DoEditorHide;
1148     var i: integer;
1149     begin
1150     inherited DoEditorHide;
1151     if assigned(EditorPanel) then
1152     for i := 0 to EditorPanel.ControlCount -1 do
1153     if EditorPanel.Controls[i] is TIBLookupComboEditBox then
1154     EditorPanel.Controls[i].Perform(CM_VISIBLECHANGED, WParam(ord(false)), 0);
1155     end;
1156    
1157     procedure TIBDynamicGrid.Loaded;
1158     begin
1159     inherited Loaded;
1160     ProcessColumns;
1161     end;
1162    
1163     function TIBDynamicGrid.CreateColumns: TGridColumns;
1164     begin
1165     result := TDBGridColumns.Create(Self, TIBDynamicGridColumn);
1166     end;
1167    
1168     procedure TIBDynamicGrid.MouseDown(Button: TMouseButton; Shift: TShiftState; X,
1169     Y: Integer);
1170     var Coord: TGridCoord;
1171     obe: boolean;
1172     function PtInRect(const Rect : TRect;const p : TPoint) : Boolean;
1173    
1174     begin
1175     PtInRect:=(p.y>=Rect.Top) and
1176     (p.y<Rect.Bottom) and
1177     (p.x>=Rect.Left) and
1178     (p.x<Rect.Right);
1179     end;
1180     begin
1181     if (Editor is TDBLookupCellEditor) and Editor.Visible
1182     and not PtInRect(Editor.BoundsRect,Point(X,Y)) then
1183     Editor.Perform(CM_EXIT,0,0); {Do insert new value if necessary}
1184     inherited MouseDown(Button, Shift, X, Y);
1185     obe := AllowOutboundEvents;
1186     AllowOutboundEvents := false;
1187     try
1188     Coord := MouseCoord(X,Y);
1189 tony 27 if AllowColumnSort and (Coord.X <> -1) and (FixedRows > 0) and
1190 tony 21 (Coord.Y = 0) and (MouseCoord(X+5,Y).X = Coord.X) {not on boundary}
1191     and (MouseCoord(X-5,Y).X = Coord.X) then
1192     ColumnHeaderClick(Coord.X-1);
1193     finally
1194     AllowOutboundEvents := obe
1195     end;
1196     end;
1197    
1198 tony 27 procedure TIBDynamicGrid.MoveSelection;
1199     begin
1200     inherited MoveSelection;
1201     SavePosition;
1202     end;
1203    
1204 tony 21 procedure TIBDynamicGrid.LinkActive(Value: Boolean);
1205     begin
1206 tony 435 DataSetChanged;
1207 tony 21 inherited LinkActive(Value);
1208     if (FActive <> Value) and Value then
1209 tony 27 RestorePosition;
1210 tony 21 FActive := Value
1211     end;
1212    
1213     procedure TIBDynamicGrid.Notification(AComponent: TComponent;
1214     Operation: TOperation);
1215 tony 39 var i: integer;
1216 tony 21 begin
1217     inherited Notification(AComponent, Operation);
1218 tony 39 if (Operation = opRemove) then
1219     begin
1220     if AComponent is TDataSource then
1221     begin
1222     for i := 0 to Columns.Count - 1 do
1223     if TIBDynamicGridColumn(Columns[I]).DBLookupProperties.ListSource = AComponent then
1224     TIBDynamicGridColumn(Columns[I]).DBLookupProperties.ListSource := nil;
1225     end
1226     end
1227 tony 21 end;
1228    
1229     procedure TIBDynamicGrid.UpdateActive;
1230     begin
1231     inherited UpdateActive;
1232 tony 435 DataSetChanged;
1233 tony 27 if assigned(DataLink) and assigned(DataLink.DataSet) and
1234     DataLink.DataSet.Active and (DataLink.DataSet.State = dsInsert) then
1235     SavePosition;
1236 tony 21 end;
1237    
1238 tony 435 procedure TIBDynamicGrid.UpdateSQL(SQLEditor : IDynamicSQLEditor);
1239     var OrderBy: string;
1240     begin
1241     SQLEditor.OrderBy(Columns[FLastColIndex].FieldName,not Descending);
1242    
1243     if assigned(FOnUpdateSortOrder) then
1244     begin
1245     OrderBy := SQLEditor.GetOrderByClause;
1246     OnUpdateSortOrder(self,FLastColIndex,OrderBy);
1247     SQLEditor.SetOrderByClause(OrderBy);
1248     end;
1249    
1250     if assigned(FOnUpdateSQL) then
1251     OnUpdateSQL(self,SQLEditor);
1252     end;
1253    
1254     procedure TIBDynamicGrid.SetParams(SQLParamProvider : IDynamicSQLParam);
1255     begin
1256     if assigned(FOnSetParams) then
1257     OnSetParams(self, SQLParamProvider);
1258     end;
1259    
1260 tony 21 constructor TIBDynamicGrid.Create(TheComponent: TComponent);
1261     begin
1262     inherited Create(TheComponent);
1263     FAllowColumnSort := true;
1264     FIndexFieldsList := TStringList.Create;
1265     FIndexFieldsList.Delimiter := ';';
1266     FIndexFieldsList.StrictDelimiter := true;
1267     FDBLookupCellEditor := TDBLookupCellEditor.Create(nil);
1268     FDBLookupCellEditor.Name := 'DBLookupCellEditor';
1269     FDBLookupCellEditor.Visible := False;
1270     FDBLookupCellEditor.AutoSize := false;
1271     end;
1272    
1273     destructor TIBDynamicGrid.Destroy;
1274     begin
1275 tony 435 if DataSet <> nil then
1276     (DataSet as IDynamicSQLDataset).UnRegisterDynamicComponent(self);
1277 tony 21 if assigned(FIndexFieldsList) then FIndexFieldsList.Free;
1278     if assigned(FDBLookupCellEditor) then FDBLookupCellEditor.Free;
1279 tony 80 Application.RemoveAsyncCalls(self);
1280 tony 21 inherited Destroy;
1281     end;
1282    
1283     function TIBDynamicGrid.EditorByStyle(Style: TColumnButtonStyle): TWinControl;
1284     var C: TIBDynamicGridColumn;
1285     bs: TColumnButtonStyle;
1286     begin
1287     C := ColumnFromGridColumn(Col) as TIBDynamicGridColumn;
1288     if C <> nil then
1289     begin
1290     bs := C.ButtonStyle;
1291     if (bs in [cbsAuto,cbsPickList]) and assigned(C.DBLookupProperties.ListSource) then
1292     begin
1293     Result := FDBLookupCellEditor;
1294     Exit;
1295     end;
1296     end;
1297     Result := inherited EditorByStyle(Style);
1298     end;
1299    
1300     end.

Properties

Name Value
svn:eol-style native