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

# Content
1 (*
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 * The Original Code is (C) 2015 Tony Whyman, MWA Software
19 * (http://www.mwasoftware.co.uk).
20 *
21 * All Rights Reserved.
22 *
23 * Contributor(s): ______________________________________.
24 *
25 *)
26
27 unit IBDynamicGrid;
28
29 {$mode objfpc}{$H+}
30
31 interface
32
33 uses
34 Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, DBGrids, DB,
35 Grids, IBLookupComboEditBox, LMessages, StdCtrls, ExtCtrls,
36 LCLVersion, IBDynamicInterfaces;
37
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 - DataSet re-sorting on header row click, sorting the dataset by the selected column.
45 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 FOnCloseUp: TNotifyEvent;
96 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 property OnCloseUp: TNotifyEvent read FOnCloseUp write FOnCloseUp;
123 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 function EditingKeyField: boolean;
154 protected
155 procedure WndProc(var TheMessage : TLMessage); override;
156 procedure CloseUp; override;
157 procedure KeyDown(var Key : Word; Shift : TShiftState); override;
158 procedure Loaded; override;
159 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 TOnSelectPanelEditor = procedure(Sender: TObject; var aEditorPanel: TWinControl) of object;
171
172 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 FOnSelectPanelEditor: TOnSelectPanelEditor;
183 FResizing: boolean;
184 FWeHaveFocus: boolean;
185 FMouseDown: boolean;
186 function ActiveControl: TControl;
187 procedure DoShowEditorPanel(Data: PtrInt);
188 procedure PositionTotals;
189 procedure KeyDownHandler(Sender: TObject; var Key: Word; Shift: TShiftState);
190 procedure PerformEditorHide(Data: PtrInt);
191 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 property VisibleRowCount;
221 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 property OnSelectPanelEditor: TOnSelectPanelEditor read FOnSelectPanelEditor
229 write FOnSelectPanelEditor;
230 end;
231
232 TLocationArray = array of variant;
233 PLocationArray = ^TLocationArray;
234 TOnRestorePosition = procedure(Sender: TObject; Location: PLocationArray) of object;
235
236 { TIBDynamicGrid }
237
238 TIBDynamicGrid = class(TDBDynamicGrid,IDynamicSQLComponent)
239 private
240 { Private declarations }
241 FAllowColumnSort: boolean;
242 FOnColumnHeaderClick: TOnColumnHeaderClick;
243 FOnRestorePosition: TOnRestorePosition;
244 FOnSetParams : TOnSetParams;
245 FOnUpdateSortOrder: TOnUpdateSortOrder;
246 FDefaultPositionAtEnd: boolean;
247 FDescending: boolean;
248 FColHeaderClick: boolean;
249 FLastColIndex: integer;
250 FIndexFieldNames: string;
251 FIndexFieldsList: TStringList;
252 FBookmark: TLocationArray;
253 FDBLookupCellEditor: TDBLookupCellEditor;
254 FActive: boolean;
255 FCurDataset: TDataSet; {reference to Dataset on last call to DataSetChanged}
256 FOnUpdateSQL : TOnUpdateSQL;
257 procedure ColumnHeaderClick(Index: integer);
258 function GetDataSet : TDataSet;
259 function GetDataSource: TDataSource;
260 function GetEditorBorderStyle: TBorderStyle;
261 procedure DataSetChanged;
262 procedure SetDataSource(AValue: TDataSource);
263 procedure SetEditorBorderStyle(AValue: TBorderStyle);
264 procedure ProcessColumns;
265 procedure SetIndexFieldNames(AValue: string);
266 procedure UpdateSortColumn(Sender: TObject);
267 procedure RestorePosition;
268 procedure SavePosition;
269 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 procedure MoveSelection; override;
279 procedure Notification(AComponent: TComponent; Operation: TOperation); override;
280 procedure UpdateActive; override;
281 {IDynamicSQLComponent}
282 procedure UpdateSQL(SQLEditor: IDynamicSQLEditor);
283 procedure SetParams(SQLParamProvider: IDynamicSQLParam);
284 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 property DataSet: TDataSet read GetDataSet;
291 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 property OnRestorePosition: TOnRestorePosition read FOnRestorePosition write FOnRestorePosition;
301 property OnUpdateSortOrder: TOnUpdateSortOrder read FOnUpdateSortOrder write FOnUpdateSortOrder;
302 property OnUpdateSQL: TOnUpdateSQL read FOnUpdateSQL write FOnUpdateSQL;
303 property OnSetParams: TOnSetParams read FOnSetParams write FOnSetParams;
304 end;
305
306 implementation
307
308 uses LCLType, Variants, EditBtn;
309
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 if (ColCount = 1) and TDBDynamicGridColumn(Columns[0]).AutoSizeColumn then
357 Columns[0].Width := ClientWidth
358 else
359 begin
360 for I := 0 to ColCount - 1 do
361 if (I < FixedCols) or Columns[I - FixedCols].Visible then
362 ColSum := ColSum + ColWidths[I];
363
364 if Colsum <> ClientWidth then
365 begin
366 ResizeColCount := 0;
367 for I := 0 to Columns.Count -1 do
368 if TDBDynamicGridColumn(Columns[I]).AutoSizeColumn and Columns[I].Visible then
369 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
375 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 if TDBDynamicGridColumn(Columns[I]).AutoSizeColumn and Columns[I].Visible then
382 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 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 if Editor = FEditorPanel then
402 begin
403 if FMouseDown then
404 Application.QueueAsyncCall(@PerformEditorHide,FExpandedRow)
405 else
406 PerformEditorHide(FExpandedRow);
407 FExpandedRow := -1;
408 end;
409 end;
410
411 procedure TDBDynamicGrid.DoEditorShow;
412 begin
413 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 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 if assigned(Editor) and Editor.Visible then
432 Editor.SetFocus;
433 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 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 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 AControl: TControl;
540 begin
541 if Visible and assigned(FEditorPanel) and FEditorPanel.Visible and FWeHaveFocus then
542 begin
543 Done := false;
544 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 and (Key in [VK_RETURN,VK_UP,VK_DOWN]) then Exit; {Ignore keys in a CustomMemo}
553
554 if (AControl <> nil) and (AControl is TCustomGrid)
555 and (Key in [VK_RETURN,VK_UP,VK_DOWN,VK_TAB]) then Exit; {Ignore keys in a Custom Grid}
556
557 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
564 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 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 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 if FEditorPanel <> nil then
608 FreeNotification(FEditorPanel);
609 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 if Visible then
637 DoGridResize
638 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 FMouseDown := true;
662 try
663 inherited MouseDown(Button, Shift, X, Y);
664 finally
665 FMouseDown := false;
666 end;
667
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 var i: integer;
676 begin
677 inherited Notification(AComponent, Operation);
678 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 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 if not (csLoading in ComponentState) and assigned(DataLink)
703 and assigned(DataLink.DataSet) and DataLink.DataSet.Active then
704 DoGridResize;
705
706 if not (csLoading in ComponentState) and assigned(DataLink) and
707 assigned(FEditorPanel) and not FEditorPanel.Visible and
708 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 EditorMode := false;
741 end;
742
743 procedure TDBDynamicGrid.ShowEditorPanel;
744 var aEditor: TWinControl;
745 begin
746 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 aEditor := FEditorPanel;
751 if assigned(FOnSelectPanelEditor) then
752 OnSelectPanelEditor(self,aEditor);
753 if FEditorPanel <> aEditor then
754 SetEditorPanel(aEditor);
755 Editor := aEditor;
756 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 type
795 THackedGrid = class(TIBDynamicGrid)
796 public
797 property FixedCols;
798 end;
799
800 { TDBLookupCellEditor }
801
802 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 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 Begin
826 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 (FGrid as TIBDynamicGrid).UpdateData;
834 end;
835 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 procedure TDBLookupCellEditor.Loaded;
847 begin
848 inherited Loaded;
849 Text := '';
850 end;
851
852 procedure TDBLookupCellEditor.msg_GetValue(var Msg: TGridMessage);
853 begin
854 CheckAndInsert;
855 Msg.Col := FCol;
856 Msg.Row := FRow;
857 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 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 Editor.OnCloseUp := OnCloseUp;
929
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 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 Editor.SelStart := Length(Editor.Text);
961 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 Application.RemoveAsyncCalls(self);
985 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 if assigned(DataSource) and assigned(DataSource.DataSet) and DataSource.DataSet.Active then
1003 begin
1004 if FLastColIndex < Columns.Count then
1005 {try and cache field position while dataset still open}
1006 DataSource.DataSet.Active := false;
1007 Application.QueueAsyncCall(@DoReopen,0)
1008 end;
1009 finally
1010 FColHeaderClick := false
1011 end;
1012 end;
1013
1014 function TIBDynamicGrid.GetDataSet : TDataSet;
1015 begin
1016 if DataSource <> nil then
1017 Result := DataSource.Dataset
1018 else
1019 Result := nil;
1020 end;
1021
1022 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 DataSetChanged;
1042 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 procedure TIBDynamicGrid.RestorePosition;
1089 begin
1090 if assigned(DataSource) and assigned(DataSource.DataSet) and DataSource.DataSet.Active then
1091 begin
1092 if assigned(FOnRestorePosition) then
1093 OnRestorePosition(self,@FBookmark);
1094 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 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 procedure TIBDynamicGrid.DoReOpen(Data: PtrInt);
1118 begin
1119 DataSource.DataSet.Active := true;
1120 end;
1121
1122 procedure TIBDynamicGrid.DataSetChanged;
1123 begin
1124 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 end;
1137
1138 procedure TIBDynamicGrid.SetupEditor(aEditor: TDBLookupCellEditor; aCol: integer
1139 );
1140 var C: TIBDynamicGridColumn;
1141 begin
1142 C := ColumnFromGridColumn(aCol) as TIBDynamicGridColumn;
1143 if (c <> nil) then
1144 C.SetupEditor(aEditor);
1145 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 if AllowColumnSort and (Coord.X <> -1) and (FixedRows > 0) and
1190 (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 procedure TIBDynamicGrid.MoveSelection;
1199 begin
1200 inherited MoveSelection;
1201 SavePosition;
1202 end;
1203
1204 procedure TIBDynamicGrid.LinkActive(Value: Boolean);
1205 begin
1206 DataSetChanged;
1207 inherited LinkActive(Value);
1208 if (FActive <> Value) and Value then
1209 RestorePosition;
1210 FActive := Value
1211 end;
1212
1213 procedure TIBDynamicGrid.Notification(AComponent: TComponent;
1214 Operation: TOperation);
1215 var i: integer;
1216 begin
1217 inherited Notification(AComponent, Operation);
1218 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 end;
1228
1229 procedure TIBDynamicGrid.UpdateActive;
1230 begin
1231 inherited UpdateActive;
1232 DataSetChanged;
1233 if assigned(DataLink) and assigned(DataLink.DataSet) and
1234 DataLink.DataSet.Active and (DataLink.DataSet.State = dsInsert) then
1235 SavePosition;
1236 end;
1237
1238 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 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 if DataSet <> nil then
1276 (DataSet as IDynamicSQLDataset).UnRegisterDynamicComponent(self);
1277 if assigned(FIndexFieldsList) then FIndexFieldsList.Free;
1278 if assigned(FDBLookupCellEditor) then FDBLookupCellEditor.Free;
1279 Application.RemoveAsyncCalls(self);
1280 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