cxdbdata.pas

来自「胜天进销存源码,国产优秀的进销存」· PAS 代码 · 共 1,895 行 · 第 1/5 页

PAS
1,895
字号
                  AFound := True;
                  Break;
                end;
            end;
            if not AFound then
            begin
              if DataController.CanSelectRow(-1) then
                FBookmarks.Add(ABkm);
            end;
          end
          else
          begin
            if DataController.CanSelectRow(-1) then
              FBookmarks.Add(ABkm);
          end;
          if CompareBookmarks(ABkm, ABkm2) = 0 then
            Break;
          Next;
        end;
      except
        FBookmarks.Clear;
        SyncCount;
        raise;
      end;
    end;
  end;

var
  ABkm1, ABkm2: TBookmarkStr;
  ADirectionDown: Boolean;
begin
  // TODO: optimize - Do Selection (up/down)
  if DataController.IsGridMode and Assigned(DataController.DataSet) then
  begin
    with DataController.Provider do
    begin
      if (DataSet.State = dsInsert) and DataSet.Eof then
        Exit; 
      Freeze;
      try
        SavePos;
        ABkm1 := FAnchorBookmark;
        ABkm2 := AToBookmark;
        ADirectionDown := CompareBookmarks(ABkm1, ABkm2) < 0;
        if not ADirectionDown then
        begin
          ABkm2 := FAnchorBookmark;
          ABkm1 := AToBookmark;
        end;
        // check - select shift + up/down
        if not CheckBookmarks(ABkm1, ABkm2, ADirectionDown) then
          LoadBookmarks(ABkm1, ABkm2);
        SyncCount;
        RestorePos;
      finally
        Unfreeze;
        Changed;
        DataController.DataControllerInfo.CheckChanges;
        DataController.SyncMasterPos;
      end;
    end;
  end;
end;

procedure TcxDBDataSelection.ClearAnchor;
begin
  inherited ClearAnchor;
  FAnchorBookmark := '';
end;

function TcxDBDataSelection.CompareBookmarks(const AItem1, AItem2: TBookmarkStr): Integer;
begin
  Result := DataController.Provider.CompareBookmarks(AItem1, AItem2);
end;

procedure TcxDBDataSelection.InternalAdd(AIndex, ARowIndex, ARecordIndex, ALevel: Integer);
begin
  inherited InternalAdd(AIndex, ARowIndex, ARecordIndex, ALevel);
  if not DataController.IsGridMode or FInSelectAll then Exit;
  FBookmarks.Insert(AIndex, GetRowBookmark(ARowIndex));
end;

procedure TcxDBDataSelection.InternalClear;
begin
  inherited InternalClear;
  if FBookmarks <> nil then
    FBookmarks.Clear;
end;

procedure TcxDBDataSelection.InternalDelete(AIndex: Integer);
begin
  inherited InternalDelete(AIndex);
  if not DataController.IsGridMode or FInSelectAll then Exit;
  if CompareBookmarks(FBookmarks[AIndex], FAnchorBookmark) = 0 then
    ClearAnchor;
  FBookmarks.Delete(AIndex);
end;

function TcxDBDataSelection.FindBookmark(const ABookmark: TBookmarkStr; var AIndex: Integer): Boolean;
var
  L, H, I, C: Integer;
begin
  AIndex := 0;
  Result := False;
  L := 0;
  H := FBookmarks.Count - 1;
  if L <= H then
    repeat
      I := (L + H) div 2;
      C := CompareBookmarks(FBookmarks[I], ABookmark);
      if C = 0 then
      begin
        AIndex := I;
        Result := True;
        Break;
      end
      else
        if C < 0 then
          L := I + 1
        else
          H := I - 1;
      if L > H then
      begin
        AIndex := L;
        Break;
      end;
    until False;
end;

function TcxDBDataSelection.GetRowBookmark(ARowIndex: Integer): TBookmarkStr;
var
  APrevActiveRecord: Integer;
begin
  Result := '';
  if not DataController.IsGridMode then Exit;
  APrevActiveRecord := DataController.Provider.DataLink.ActiveRecord;
  try
    DataController.Provider.DataLink.ActiveRecord := ARowIndex;
    Result := DataController.DataSet.Bookmark;
  finally
    DataController.Provider.DataLink.ActiveRecord := APrevActiveRecord;
  end;
end;

function TcxDBDataSelection.RefreshBookmarks: Boolean;
var
  I: Integer;
  ADataSet: TDataSet;
begin
  Result := False;
  if not DataController.IsGridMode then Exit;
  ADataSet := DataController.DataSet;
  if Assigned(ADataSet) then
    for I := Count - 1 downto 0 do
    begin
      if (FBookmarks[I] = '') or
        not DataController.Provider.BookmarkValid(FBookmarks[I]) then
        begin
          Result := True;
          Delete(I);
        end;
    end;
end;

procedure TcxDBDataSelection.SyncCount;
begin
  FInSelectAll := True;
  try
    SetInternalCount(FBookmarks.Count);
  finally
    FInSelectAll := False;
  end;  
end;

function TcxDBDataSelection.GetDataController: TcxDBDataController;
begin
  Result := inherited DataController as TcxDBDataController;
end;

{ TcxDBDataLink }

constructor TcxDBDataLink.Create(AProvider: TcxDBDataProvider);
begin
  inherited Create;
  FProvider := AProvider;
  VisualControl := True;
end;

procedure TcxDBDataLink.ActiveChanged;
begin
  Provider.ActiveChanging := True;
  try
    Provider.ActiveChanged(Active);
    if Provider.DataController.IsLoading then
      Provider.DataController.FLoaded := True;
  finally
    Provider.ActiveChanging := False;
  end;
  Provider.FInSetDataSource := Assigned(DataSet) and (DataSet.State = dsInsert);
{$IFDEF DELPHI7}
  if not Active then
    FLayoutChangedFlag := False;
{$ENDIF}
end;

{$IFDEF DELPHI7}
procedure TcxDBDataLink.DataEvent(Event: TDataEvent;
  Info: Integer);
begin
  inherited DataEvent(Event, Info);
  if (Event = deDisabledStateChange) and not Boolean(Info) then
    FLayoutChangedFlag := True;
end;
{$ENDIF}

procedure TcxDBDataLink.DataSetChanged;
begin
  {$IFDEF DELPHI7}
  if FLayoutChangedFlag then
  begin
    LayoutChanged;
    Exit;
  end;
  {$ENDIF}
  if Provider.IsOtherDataControllerUpdating then Exit;
  if Provider.IsOtherDetailChanged then Exit;
{
  if Provider.IsGridMode and Provider.DataController.IsDetailMode and
    not VarEquals(GetDataSetValues(DataSet, Provider.DataController.MasterDetailKeyFields),
      Provider.DataController.MasterDetailKeyValues) then
    Exit;
}
  if Provider.IsDataSetBusy then
    DataSetScrolled(0)
  else
  begin
    if Provider.IsGridMode then
    begin
      Provider.FInUpdateGridMode := True;
      try
        Provider.DataController.BeginFullUpdate;
        try
          Provider.UpdateGridMode;
          if Provider.DataController.MultiSelect then
            Provider.DataController.DBSelection.RefreshBookmarks;
          Provider.DataController.CheckBookmarkValid(-1);
          if DataSet.State = dsInsert then
            DoInsertingRecord;
        finally
          Provider.DataController.EndFullUpdate;
        end;
        Provider.CheckExpandedDetails;
      finally
        Provider.FInUpdateGridMode := False;
      end;
//      if DataSet.State = dsInsert then
//        Provider.InsertingRecord(Provider.IsEOF);
    end
    else
    begin
      if not (DataSet.State in dsEditModes) then
      begin
        if Provider.IsSmartRefresh then
        begin
          Provider.SmartDataChanged;
          DataSetScrolled(0);
        end
        else
        begin
          Provider.DataChanged(dcTotal, -1, -1);
          DataSetScrolled(0);  // AB16340 (alternative: Provider.DataController.UpdateFocused;)
        end;
        Provider.ResetSmartRefresh;
      end
      else
        if (DataSet.State = dsInsert) and not Provider.FInserting then
        begin
          if (not Provider.DataController.IsDetailMode or Provider.IsDataSetCurrent) and
            Provider.IsSyncInsert and not Provider.FInInserting then
            DoInsertingRecord;
        end;
    end;
  end;
end;

procedure TcxDBDataLink.DataSetScrolled(Distance: Integer);
begin
  Provider.DataScrolled(Distance);
end;

procedure TcxDBDataLink.EditingChanged;
begin
  if not Provider.IsSyncMode then Exit;
  if not Active or not (DataSet.State in dsEditModes) then
  begin
    if {not Provider.IsGridMode and} Provider.IsSmartRefresh and
      (Provider.EditingRecordIndex <> cxNullEditingRecordIndex) and
      (Provider.EditingRecordIndex = Provider.DataController.NewItemRecordIndex) then
    begin
      if Provider.FUpdatingRecordIsInserting then
      begin
        Provider.DataController.FInUnboundCopy := True; // !!!
        try
          Provider.FUpdatingNewRecordIndex := Provider.DataController.AppendRecord;
          Provider.DataController.CopyRecord(Provider.DataController.NewItemRecordIndex,
            Provider.FUpdatingNewRecordIndex);
        finally
          Provider.DataController.FInUnboundCopy := False;
        end;
      end;
    end;
    Provider.ResetEditing;
  end
  else
  begin
    if DataSet.State = dsEdit then
    begin
      Provider.DataController.FInUnboundCopy := TRue;
      try
        Provider.EditingRecord;
      finally
        Provider.DataController.FInUnboundCopy := False;
      end;
    end
    else
      if (DataSet.State = dsInsert) and not DataSet.ControlsDisabled and
        (Provider.FInSetDataSource or Provider.DataController.FInUpdateGridModeBufferCount) then
      begin
        if Provider.IsGridMode and not Provider.FInInsert then
          DoInsertingRecord;
      end;
  end;
  Provider.FInSetDataSource := False;
end;

procedure TcxDBDataLink.FocusControl(Field: TFieldRef);

  function FindItemIndex(AField: TField): Integer;
  var
    I: Integer;
    ADataField: TcxDBDataField;
  begin
    Result := -1;
    for I := 0 to Provider.DataController.Fields.Count - 1 do
    begin
      ADataField := Provider.DataController.DBFields[I];
      if not ADataField.IsInternal and (ADataField.Field = AField) then
      begin
        Result := I;
        Break;
      end;
    end;
  end;

var
  ADone: Boolean;
  AItemIndex: Integer;
begin
  if Assigned(Field) and Assigned(Field^) then
  begin
    ADone := False;
    AItemIndex := FindItemIndex(Field^);
    if (AItemIndex <> -1) and (AItemIndex < Provider.DataController.GetItemCount) then
    begin
      Provider.DataController.FocusControl(AItemIndex, ADone);
      if ADone then
        Field^ := nil;
    end;    
  end;
end;

procedure TcxDBDataLink.LayoutChanged;
begin
  {$IFDEF DELPHI7} // bug in Delphi 7 with update pack 1
  if (DataSet.State = dsInsert) or
    (Provider.IsSmartRefresh and FPreventLayoutChanged) then
  begin
    DataSetChanged;
    Exit;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?