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 29 by tony, Sat May 9 11:37:49 2015 UTC vs.
Revision 37 by tony, Mon Feb 15 14:44:25 2016 UTC

# Line 23 | Line 23
23   *  Contributor(s): ______________________________________.
24   *
25   *)
26 +
27   unit IBDynamicGrid;
28  
29   {$mode objfpc}{$H+}
# Line 91 | Line 92 | type
92      FListSource: TDataSource;
93      FOnAutoInsert: TAutoInsert;
94      FOnCanAutoInsert: TCanAutoInsert;
95 +    FOnCloseUp: TNotifyEvent;
96      FOnDrawItem: TDrawItemEvent;
97      FOwner: TIBDynamicGridColumn;
98      FRelationName: string;
# Line 117 | Line 119 | type
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  
# Line 177 | Line 180 | end;
180      FWeHaveFocus: boolean;
181      FHidingEditorPanel: boolean;
182      FAllowHide: boolean;
183 +    FMouseDown: boolean;
184 +    function ActiveControl: TControl;
185      procedure DoShowEditorPanel(Data: PtrInt);
186      procedure PositionTotals;
187      procedure KeyDownHandler(Sender: TObject; var Key: Word; Shift: TShiftState);
188 +    procedure PerformEditorHide(Data: PtrInt);
189      procedure SetEditorPanel(AValue: TWinControl);
190    protected
191      procedure ChangeBounds(ALeft, ATop, AWidth, AHeight: integer; KeepBase: boolean); override;
# Line 253 | Line 259 | end;
259      FBookmark: TLocationArray;
260      FDBLookupCellEditor: TDBLookupCellEditor;
261      FActive: boolean;
262 +    FFieldPosition: integer;
263      procedure ColumnHeaderClick(Index: integer);
264      function GetDataSource: TDataSource;
265      function GetEditorBorderStyle: TBorderStyle;
# Line 358 | Line 365 | begin
365    FResizing := true;
366    try
367      ColSum := 0;
361    for I := 0 to  ColCount - 1 do
362       ColSum := ColSum + ColWidths[I];
368  
369 <    if Colsum <> ClientWidth then
369 >    if (ColCount = 1) and TDBDynamicGridColumn(Columns[0]).AutoSizeColumn then
370 >      Columns[0].Width := ClientWidth
371 >    else
372      begin
373 <      ResizeColCount := 0;
374 <      for I := 0 to Columns.Count -1 do
375 <        if TDBDynamicGridColumn(Columns[I]).AutoSizeColumn then
376 <        begin
377 <          Inc(ResizeColCount);
378 <          Colsum := Colsum + TDBDynamicGridColumn(Columns[I]).DesignWidth - Columns[I].Width;
379 <          Columns[I].Width := TDBDynamicGridColumn(Columns[I]).DesignWidth;
380 <        end;
381 <
382 <        if (Colsum < ClientWidth) and (ResizeColCount > 0) then
383 <        begin
384 <          adjustment := (ClientWidth - ColSum) div ResizeColCount;
385 <          n := (ClientWidth - ColSum) mod ResizeColCount;
386 <
387 <          for I := 0 to Columns.Count -1 do
388 <            if TDBDynamicGridColumn(Columns[I]).AutoSizeColumn then
389 <            begin
390 <              if I = 0 then
391 <                Columns[I].Width := Columns[I].Width + adjustment + n
392 <              else
393 <                Columns[I].Width := Columns[I].Width + adjustment;
394 <            end;
395 <        end;
373 >      for I := 0 to  ColCount - 1 do
374 >         ColSum := ColSum + ColWidths[I];
375 >
376 >      if Colsum <> ClientWidth then
377 >      begin
378 >        ResizeColCount := 0;
379 >        for I := 0 to Columns.Count -1 do
380 >          if TDBDynamicGridColumn(Columns[I]).AutoSizeColumn then
381 >          begin
382 >            Inc(ResizeColCount);
383 >            Colsum := Colsum + TDBDynamicGridColumn(Columns[I]).DesignWidth - Columns[I].Width;
384 >            Columns[I].Width := TDBDynamicGridColumn(Columns[I]).DesignWidth;
385 >          end;
386 >
387 >          if (Colsum < ClientWidth) and (ResizeColCount > 0) then
388 >          begin
389 >            adjustment := (ClientWidth - ColSum) div ResizeColCount;
390 >            n := (ClientWidth - ColSum) mod ResizeColCount;
391 >
392 >            for I := 0 to Columns.Count -1 do
393 >              if TDBDynamicGridColumn(Columns[I]).AutoSizeColumn then
394 >              begin
395 >                if I = 0 then
396 >                  Columns[I].Width := Columns[I].Width + adjustment + n
397 >                else
398 >                  Columns[I].Width := Columns[I].Width + adjustment;
399 >              end;
400 >          end;
401 >      end;
402      end;
403      PositionTotals;
404      UpdateEditorPanelBounds;
# Line 399 | Line 412 | begin
412    inherited DoEditorHide;
413    if Editor = FEditorPanel then
414    begin
415 <    if (FExpandedRow >= 0) and (FExpandedRow < RowCount) then
416 <      RowHeights[FExpandedRow] := DefaultRowHeight;
415 >    if FMouseDown then
416 >      Application.QueueAsyncCall(@PerformEditorHide,FExpandedRow)
417 >    else
418 >      PerformEditorHide(FExpandedRow);
419      FExpandedRow := -1;
405    if CanFocus then SetFocus;
406    if assigned(FOnEditorPanelHide) then
407       OnEditorPanelHide(self);
408    DoOnResize;
409    ResetSizes;
410    DoOnChangeBounds;
420    end;
421   end;
422  
423   procedure TDBDynamicGrid.DoEditorShow;
424   begin
425 +  if assigned(DataSource) and assigned(DataSource.DataSet) and
426 +             DataSource.DataSet.Active then
427 +  begin
428 +    if (DataSource.DataSet.RecordCount = 0) and (DataSource.DataSet.State <> dsInsert) then
429 +      DataSource.DataSet.Append
430 +  end;
431    if Editor = FEditorPanel then
432    begin
433      if ExpandEditorPanelBelowRow then
# Line 425 | Line 440 | begin
440      FEditorPanel.PerformTab(true);  {Select First Control}
441      if assigned(FOnEditorPanelShow) then
442         OnEditorPanelShow(self);
443 +    if assigned(Editor) and Editor.Visible then
444 +      Editor.SetFocus;
445    end
446    else
447      inherited DoEditorShow;
# Line 489 | Line 506 | begin
506      inherited KeyDown(Key, Shift);
507   end;
508  
509 + function TDBDynamicGrid.ActiveControl: TControl;
510 + var AParent: TWinControl;
511 + begin
512 +  Result := nil;
513 +  AParent := Parent;
514 +  while (AParent <> nil) and  not (AParent is TCustomForm) do
515 +    AParent := AParent.Parent;
516 +  if (AParent <> nil) and (AParent is TCustomForm)then
517 +      Result := TCustomForm(AParent).ActiveControl;
518 + end;
519 +
520   procedure TDBDynamicGrid.DoShowEditorPanel(Data: PtrInt);
521   begin
522    if AppDestroying in Application.Flags then Exit;
# Line 520 | Line 548 | end;
548   procedure TDBDynamicGrid.KeyDownHandler(Sender: TObject; var Key: Word;
549    Shift: TShiftState);
550   var Done: boolean;
551 +    AControl: TControl;
552   begin
553    if Visible and assigned(FEditorPanel) and FEditorPanel.Visible and FWeHaveFocus then
554    begin
555      Done := false;
556 +    AControl := ActiveControl;
557 +    if (AControl <> nil) and (AControl is TCustomComboBox)
558 +                         and ((Key in [VK_UP,VK_DOWN]) or
559 +                         (TCustomComboBox(AControl).DroppedDown and (Key = VK_RETURN)) or
560 +                         ((TCustomComboBox(AControl).Text <> '') and (Key =  VK_ESCAPE))) then
561 +      Exit; {ignore these keys if we are in a  combobox}
562 +
563 +    if (AControl <> nil) and (AControl is TCustomMemo)
564 +                         and (Key in [VK_RETURN,VK_UP,VK_DOWN]) then Exit; {Ignore Return in a CustomMemo}
565 +
566 +    if (AControl <> nil) and (AControl is TCustomGrid)
567 +                         and (Key in [VK_RETURN,VK_UP,VK_DOWN,VK_TAB]) then Exit; {Ignore Return in a CustomMemo}
568 +
569      if assigned(FOnKeyDownHander) then
570        OnKeyDownHander(Sender,Key,Shift,Done);
571      if Done then Exit;
# Line 546 | Line 588 | begin
588    end
589   end;
590  
591 + procedure TDBDynamicGrid.PerformEditorHide(Data: PtrInt);
592 + var ExpandedRow: integer;
593 + begin
594 +  if AppDestroying in Application.Flags then Exit;
595 +  ExpandedRow := integer(Data);
596 +  if (ExpandedRow >= 0) and (ExpandedRow < RowCount) then
597 +    RowHeights[ExpandedRow] := DefaultRowHeight;
598 +  if CanFocus then SetFocus;
599 +  DoOnResize;
600 +  ResetSizes;
601 +  DoOnChangeBounds;
602 +  if assigned(FOnEditorPanelHide) then
603 +     OnEditorPanelHide(self);
604 + end;
605 +
606   procedure TDBDynamicGrid.SetEditorPanel(AValue: TWinControl);
607   begin
608    if FEditorPanel = AValue then Exit;
# Line 580 | Line 637 | begin
637    inherited Loaded;
638    if assigned(FEditorPanel) and not (csDesigning in ComponentState)then
639      FEditorPanel.Visible := false;
640 <  DoGridResize
640 >  if Visible then
641 >    DoGridResize
642   end;
643  
644   procedure TDBDynamicGrid.DoOnResize;
# Line 604 | Line 662 | procedure TDBDynamicGrid.MouseDown(Butto
662    Y: Integer);
663   var Coord: TGridCoord;
664   begin
665 <  inherited MouseDown(Button, Shift, X, Y);
665 >  FMouseDown := true;
666 >  try
667 >    inherited MouseDown(Button, Shift, X, Y);
668 >  finally
669 >    FMouseDown := false;
670 >  end;
671  
672    Coord := MouseCoord(X,Y);
673    if (Coord.X = 0) and (Coord.Y > 0) then
# Line 630 | Line 693 | begin
693    inherited UpdateActive;
694  
695    if not (csLoading in ComponentState) and assigned(DataLink) and
696 +     assigned(FEditorPanel) and not FEditorPanel.Visible and
697       assigned(DataLink.DataSet) and (DataLink.DataSet.State = dsInsert) then
698       Application.QueueAsyncCall(@DoShowEditorPanel,0);
699   end;
# Line 662 | Line 726 | end;
726   procedure TDBDynamicGrid.HideEditorPanel;
727   begin
728    if Editor = FEditorPanel then
729 <    EditorMode := false;
729 >      EditorMode := false;
730   end;
731  
732   procedure TDBDynamicGrid.ShowEditorPanel;
# Line 770 | Line 834 | begin
834    FCol := Msg.Col;
835    FRow := Msg.Row;
836    FEditText := Msg.Value;
773  SelStart := Length(Text);
837    TIBDynamicGrid(FGrid).SetupEditor(self,FCol);
838   end;
839  
# Line 819 | Line 882 | begin
882      Editor.OnAutoInsert := OnAutoInsert;
883      Editor.OnCanAutoInsert := OnCanAutoInsert;
884      Editor.OnDrawItem := OnDrawItem;
885 +    Editor.OnCloseUp := OnCloseUp;
886  
887      {Setup Data Links}
888      if KeyField <> '' then
# Line 844 | Line 908 | begin
908          Editor.DataSource := TDBGrid(Grid).DataSource;
909    end;
910    Editor.Text := Editor.FEditText;
911 +  Editor.SelStart := Length(Editor.Text);
912   end;
913  
914   procedure TIBDynamicGridColumn.SetInitialSortColumn(AValue: boolean);
# Line 884 | Line 949 | begin
949        OnColumnHeaderClick(self,Index);
950  
951      FLastColIndex := Index;
952 <    if assigned(DataSource) and assigned(DataSource.DataSet) and DataSource.DataSet.Active then
952 >    FFieldPosition := 0;
953 >    if assigned(DataSource) and assigned(DataSource.DataSet) and DataSource.DataSet.Active
954 >       and (DataSource.DataSet is TIBParserDataSet) then
955      begin
956 +      if FLastColIndex < Columns.Count then
957 +      {try and cache field position while dataset still open}
958 +        FFieldPosition := TIBParserDataSet(DataSource.DataSet).Parser.GetFieldPosition(Columns[FLastColIndex].FieldName);
959        DataSource.DataSet.Active := false;
960        Application.QueueAsyncCall(@DoReopen,0)
961      end;
# Line 933 | Line 1003 | begin
1003    for i := 0 to Columns.Count - 1 do
1004    begin
1005      if TIBDynamicGridColumn(columns[i]).InitialSortColumn then
1006 +    begin
1007 +      FFieldPosition := 0;
1008        FLastColIndex := i
1009 +    end
1010    end
1011   end;
1012  
# Line 950 | Line 1023 | end;
1023  
1024   procedure TIBDynamicGrid.UpdateSQL(Sender: TObject; Parser: TSelectSQLParser);
1025   var OrderBy: string;
953    FieldPosition: integer;
1026   begin
1027      if assigned(DataSource) and assigned(DataSource.DataSet)
1028        and (DataSource.DataSet is TIBCustomDataSet) then
1029      begin
1030 <      if (FLastColIndex < 0) or (FLastColIndex >= Columns.Count) then Exit;
1031 <      FieldPosition := Parser.GetFieldPosition(Columns[FLastColIndex].FieldName);
1032 <      if FieldPosition = 0 then Exit;
1033 <
1034 <      if Descending then
1035 <        Parser.OrderByClause := IntToStr(FieldPosition) + ' desc'
1036 <      else
1037 <        Parser.OrderByClause := IntToStr(FieldPosition) + ' asc';
1030 >      if (FFieldPosition = 0) and (FLastColIndex >= 0) and (FLastColIndex < Columns.Count) then
1031 >        {Not cached - let's hope we can find it before the dataset is opened.
1032 >         Won't work if dynamic columns}
1033 >        FFieldPosition := Parser.GetFieldPosition(Columns[FLastColIndex].FieldName);
1034 >      if FFieldPosition > 0 then
1035 >      begin
1036 >        if Descending then
1037 >          Parser.OrderByClause := IntToStr(FFieldPosition) + ' desc'
1038 >        else
1039 >          Parser.OrderByClause := IntToStr(FFieldPosition) + ' asc';
1040 >      end;
1041  
1042        if assigned(FOnUpdateSortOrder) then
1043        begin

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines