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

Comparing ibx/trunk/ibcontrols/IBDynamicGrid.pas (file contents):
Revision 35 by tony, Tue Jan 26 14:38:47 2016 UTC vs.
Revision 80 by tony, Mon Jan 1 11:31:07 2018 UTC

# Line 150 | Line 150 | end;
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;
# Line 166 | Line 167 | end;
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 }
# Line 176 | Line 179 | end;
179      FOnEditorPanelHide: TNotifyEvent;
180      FOnEditorPanelShow: TNotifyEvent;
181      FOnKeyDownHander: TKeyDownHandler;
182 +    FOnSelectPanelEditor: TOnSelectPanelEditor;
183      FResizing: boolean;
184      FWeHaveFocus: boolean;
185      FHidingEditorPanel: boolean;
# Line 223 | Line 227 | end;
227      property OnEditorPanelShow: TNotifyEvent read FOnEditorPanelShow write FOnEditorPanelShow;
228      property OnEditorPanelHide: TNotifyEvent read FOnEditorPanelHide write FOnEditorPanelHide;
229      property OnKeyDownHander: TKeyDownHandler read FOnKeyDownHander write FOnKeyDownHander;
230 +    property OnSelectPanelEditor: TOnSelectPanelEditor read FOnSelectPanelEditor
231 +                                                       write FOnSelectPanelEditor;
232   end;
233  
234    {TIBGridControlLink}
# Line 259 | Line 265 | end;
265      FBookmark: TLocationArray;
266      FDBLookupCellEditor: TDBLookupCellEditor;
267      FActive: boolean;
268 +    FFieldPosition: integer;
269      procedure ColumnHeaderClick(Index: integer);
270      function GetDataSource: TDataSource;
271      function GetEditorBorderStyle: TBorderStyle;
# Line 304 | Line 311 | end;
311  
312   implementation
313  
314 < uses Math, IBQuery, LCLType;
314 > uses LCLType, Variants, EditBtn;
315  
316   { TIBGridControlLink }
317  
# Line 370 | Line 377 | begin
377      else
378      begin
379        for I := 0 to  ColCount - 1 do
380 +        if (I < FixedCols) or Columns[I - FixedCols].Visible then
381           ColSum := ColSum + ColWidths[I];
382  
383        if Colsum <> ClientWidth then
384        begin
385          ResizeColCount := 0;
386          for I := 0 to Columns.Count -1 do
387 <          if TDBDynamicGridColumn(Columns[I]).AutoSizeColumn then
387 >          if TDBDynamicGridColumn(Columns[I]).AutoSizeColumn and Columns[I].Visible then
388            begin
389              Inc(ResizeColCount);
390              Colsum := Colsum + TDBDynamicGridColumn(Columns[I]).DesignWidth - Columns[I].Width;
# Line 389 | Line 397 | begin
397              n := (ClientWidth - ColSum) mod ResizeColCount;
398  
399              for I := 0 to Columns.Count -1 do
400 <              if TDBDynamicGridColumn(Columns[I]).AutoSizeColumn then
400 >              if TDBDynamicGridColumn(Columns[I]).AutoSizeColumn and Columns[I].Visible then
401                begin
402                  if I = 0 then
403                    Columns[I].Width := Columns[I].Width + adjustment + n
# Line 560 | Line 568 | begin
568        Exit; {ignore these keys if we are in a  combobox}
569  
570      if (AControl <> nil) and (AControl is TCustomMemo)
571 <                         and (Key in [VK_RETURN,VK_UP,VK_DOWN]) then Exit; {Ignore Return in a CustomMemo}
571 >                         and (Key in [VK_RETURN,VK_UP,VK_DOWN]) then Exit; {Ignore keys in a CustomMemo}
572  
573      if (AControl <> nil) and (AControl is TCustomGrid)
574 <                         and (Key in [VK_RETURN,VK_UP,VK_DOWN,VK_TAB]) then Exit; {Ignore Return in a CustomMemo}
574 >                         and (Key in [VK_RETURN,VK_UP,VK_DOWN,VK_TAB]) then Exit; {Ignore keys in a Custom Grid}
575 >
576 >    if (AControl <> nil) and (AControl is TEBEdit) and (AControl.Owner is TDateEdit) then
577 >    begin
578 >      if (Key in [VK_LEFT,VK_RIGHT]) then Exit; {Ignore navigation keys}
579 >      if TDateEdit(AControl.Owner).DroppedDown and
580 >        (Key in [VK_RETURN,VK_UP,VK_DOWN,VK_ESCAPE]) then Exit; {Ignore TCalender navigation keys in a Data edit}
581 >    end;
582  
583      if assigned(FOnKeyDownHander) then
584        OnKeyDownHander(Sender,Key,Shift,Done);
# Line 608 | Line 623 | begin
623    if FEditorPanel <> nil then
624       RemoveFreeNotification(FEditorPanel);
625    FEditorPanel := AValue;
626 <  FreeNotification(FEditorPanel);
626 >  if FEditorPanel <> nil then
627 >     FreeNotification(FEditorPanel);
628   end;
629  
630   procedure TDBDynamicGrid.ChangeBounds(ALeft, ATop, AWidth, AHeight: integer;
# Line 675 | Line 691 | end;
691  
692   procedure TDBDynamicGrid.Notification(AComponent: TComponent;
693    Operation: TOperation);
694 + var i: integer;
695   begin
696    inherited Notification(AComponent, Operation);
697 <  if (Operation = opRemove) and
698 <     (AComponent = FEditorPanel) then FEditorPanel := nil;
697 >  if (Operation = opRemove) and not (csDestroying in ComponentState) then
698 >  begin
699 >    if AComponent = FEditorPanel then
700 >      FEditorPanel := nil
701 >    else
702 >    if AComponent is TControl then
703 >    begin
704 >      for i := 0 to Columns.Count - 1 do
705 >        if TDBDynamicGridColumn(Columns[I]).ColumnTotalsControl = AComponent then
706 >          TDBDynamicGridColumn(Columns[I]).ColumnTotalsControl := nil;
707 >    end;
708 >  end
709   end;
710  
711   procedure TDBDynamicGrid.TopLeftChanged;
# Line 691 | Line 718 | procedure TDBDynamicGrid.UpdateActive;
718   begin
719    inherited UpdateActive;
720  
721 +  if not (csLoading in ComponentState) and assigned(DataLink)
722 +                       and assigned(DataLink.DataSet) and DataLink.DataSet.Active then
723 +    DoGridResize;
724 +
725    if not (csLoading in ComponentState) and assigned(DataLink) and
726       assigned(FEditorPanel) and not FEditorPanel.Visible and
727       assigned(DataLink.DataSet) and (DataLink.DataSet.State = dsInsert) then
# Line 729 | Line 760 | begin
760   end;
761  
762   procedure TDBDynamicGrid.ShowEditorPanel;
763 + var aEditor: TWinControl;
764   begin
765    if (csDesigning in ComponentState) or
766     (DataSource = nil) or (DataSource.DataSet = nil)
767       or ((DataSource.DataSet.RecordCount = 0) and (DataSource.DataSet.State <> dsInsert)) then
768       Exit;
769 <  Editor := FEditorPanel;
769 >  aEditor := FEditorPanel;
770 >  if assigned(FOnSelectPanelEditor) then
771 >    OnSelectPanelEditor(self,aEditor);
772 >  if FEditorPanel <> aEditor then
773 >    SetEditorPanel(aEditor);
774 >  Editor := aEditor;
775    EditorMode := true;
776   end;
777  
# Line 773 | Line 810 | begin
810    Result := inherited Width
811   end;
812  
813 + type
814 +  THackedGrid = class(TIBDynamicGrid)
815 +  public
816 +    property FixedCols;
817 +  end;
818 +
819   { TDBLookupCellEditor }
820  
821 + function TDBLookupCellEditor.EditingKeyField: boolean;
822 + begin
823 +  with TIBDynamicGridColumn(TDBGrid(FGrid).Columns[FCol - THackedGrid(FGrid).FixedCols]) do
824 +    Result := CompareText(FieldName, DBLookupProperties.DataFieldName) = 0;
825 + end;
826 +
827   procedure TDBLookupCellEditor.WndProc(var TheMessage: TLMessage);
828   begin
829    if TheMessage.msg=LM_KILLFOCUS then begin
# Line 793 | Line 842 | begin
842    UpdateData(nil); {Force Record Update}
843    if FGrid<>nil then
844    Begin
845 <    (FGrid as TIBDynamicGrid).EditorTextChanged(FCol, FRow, Trim(Text));
845 >    if EditingKeyField then
846 >    begin
847 >      if not VarIsNull(KeyValue) then
848 >       (FGrid as TIBDynamicGrid).EditorTextChanged(FCol, FRow, KeyValue)
849 >    end
850 >    else
851 >      (FGrid as TIBDynamicGrid).EditorTextChanged(FCol, FRow, Trim(Text));
852      (FGrid as TIBDynamicGrid).UpdateData;
853    end;
854    inherited CloseUp;
# Line 818 | Line 873 | begin
873    CheckAndInsert;
874    Msg.Col := FCol;
875    Msg.Row := FRow;
876 <  Msg.Value:= Trim(Text);
876 >  if EditingKeyField then
877 >  begin
878 >    if not VarIsNull(KeyValue) then
879 >      Msg.Value:= KeyValue
880 >    else
881 >      Msg.Value:= ''
882 >  end
883 >  else
884 >    Msg.Value:= Trim(Text);
885   end;
886  
887   procedure TDBLookupCellEditor.msg_SetGrid(var Msg: TGridMessage);
# Line 906 | Line 969 | begin
969      if DataFieldName <> '' then
970          Editor.DataSource := TDBGrid(Grid).DataSource;
971    end;
972 <  Editor.Text := Editor.FEditText;
972 >  if Editor.EditingKeyField then
973 >  begin
974 >    if not Field.IsNull then
975 >      Editor.KeyValue := Editor.FEditText
976 >  end
977 >  else
978 >    Editor.Text := Editor.FEditText;
979    Editor.SelStart := Length(Editor.Text);
980   end;
981  
# Line 931 | Line 1000 | end;
1000   destructor TIBDynamicGridColumn.Destroy;
1001   begin
1002    if assigned(FDBLookupProperties) then FDBLookupProperties.Free;
1003 +  Application.RemoveAsyncCalls(self);
1004    inherited Destroy;
1005   end;
1006  
# Line 948 | Line 1018 | begin
1018        OnColumnHeaderClick(self,Index);
1019  
1020      FLastColIndex := Index;
1021 <    if assigned(DataSource) and assigned(DataSource.DataSet) and DataSource.DataSet.Active then
1021 >    FFieldPosition := 0;
1022 >    if assigned(DataSource) and assigned(DataSource.DataSet) and DataSource.DataSet.Active
1023 >       and (DataSource.DataSet is TIBParserDataSet) then
1024      begin
1025 +      if FLastColIndex < Columns.Count then
1026 +      {try and cache field position while dataset still open}
1027 +        FFieldPosition := TIBParserDataSet(DataSource.DataSet).Parser.GetFieldPosition(Columns[FLastColIndex].FieldName);
1028        DataSource.DataSet.Active := false;
1029        Application.QueueAsyncCall(@DoReopen,0)
1030      end;
# Line 997 | Line 1072 | begin
1072    for i := 0 to Columns.Count - 1 do
1073    begin
1074      if TIBDynamicGridColumn(columns[i]).InitialSortColumn then
1075 +    begin
1076 +      FFieldPosition := 0;
1077        FLastColIndex := i
1078 +    end
1079    end
1080   end;
1081  
# Line 1014 | Line 1092 | end;
1092  
1093   procedure TIBDynamicGrid.UpdateSQL(Sender: TObject; Parser: TSelectSQLParser);
1094   var OrderBy: string;
1017    FieldPosition: integer;
1095   begin
1096      if assigned(DataSource) and assigned(DataSource.DataSet)
1097        and (DataSource.DataSet is TIBCustomDataSet) then
1098      begin
1099 <      if (FLastColIndex < 0) or (FLastColIndex >= Columns.Count) then Exit;
1100 <      FieldPosition := Parser.GetFieldPosition(Columns[FLastColIndex].FieldName);
1101 <      if FieldPosition > 0 then
1099 >      if (FFieldPosition = 0) and (FLastColIndex >= 0) and (FLastColIndex < Columns.Count) then
1100 >        {Not cached - let's hope we can find it before the dataset is opened.
1101 >         Won't work if dynamic columns}
1102 >        FFieldPosition := Parser.GetFieldPosition(Columns[FLastColIndex].FieldName);
1103 >      if FFieldPosition > 0 then
1104        begin
1105          if Descending then
1106 <          Parser.OrderByClause := IntToStr(FieldPosition) + ' desc'
1106 >          Parser.OrderByClause := IntToStr(FFieldPosition) + ' desc'
1107          else
1108 <          Parser.OrderByClause := IntToStr(FieldPosition) + ' asc';
1108 >          Parser.OrderByClause := IntToStr(FFieldPosition) + ' asc';
1109        end;
1110  
1111        if assigned(FOnUpdateSortOrder) then
# Line 1170 | Line 1249 | end;
1249  
1250   procedure TIBDynamicGrid.Notification(AComponent: TComponent;
1251    Operation: TOperation);
1252 + var i: integer;
1253   begin
1254    inherited Notification(AComponent, Operation);
1255 <  if (Operation = opRemove) and
1256 <     (FIBControlLink <> nil) and (AComponent = DataSource) then FIBControlLink.IBDataSet := nil;
1255 >  if (Operation = opRemove) then
1256 >  begin
1257 >    if (FIBControlLink <> nil) and (AComponent = DataSource) then
1258 >      FIBControlLink.IBDataSet := nil
1259 >    else
1260 >    if AComponent is TDataSource then
1261 >    begin
1262 >      for i := 0 to Columns.Count - 1 do
1263 >        if TIBDynamicGridColumn(Columns[I]).DBLookupProperties.ListSource = AComponent then
1264 >          TIBDynamicGridColumn(Columns[I]).DBLookupProperties.ListSource := nil;
1265 >    end
1266 >  end
1267   end;
1268  
1269   procedure TIBDynamicGrid.UpdateActive;
# Line 1203 | Line 1293 | begin
1293    if assigned(FIBControlLink) then FIBControlLink.Free;
1294    if assigned(FIndexFieldsList) then FIndexFieldsList.Free;
1295    if assigned(FDBLookupCellEditor) then FDBLookupCellEditor.Free;
1296 +  Application.RemoveAsyncCalls(self);
1297    inherited Destroy;
1298   end;
1299  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines