ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/public/ibx/trunk/ibcontrols/IBDynamicGrid.pas
Revision: 39
Committed: Tue May 17 08:14:52 2016 UTC (8 years, 5 months ago) by tony
Content type: text/x-pascal
File size: 39412 byte(s)
Log Message:
Committing updates for Release R1-4-1

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