cxdbdata.pas

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

PAS
1,895
字号
      ftBoolean:
        Result := TcxBooleanValueType;
      ftCurrency, ftFloat:
        Result := TcxFloatValueType;
      {ftCurrency, }ftBCD:
        Result := TcxCurrencyValueType;
      ftDate, ftTime, ftDateTime:
        Result := TcxDateTimeValueType;
    {$IFDEF DELPHI6}
      ftFMTBcd:
        Result := TcxFMTBcdValueType;
      ftLargeint:
        Result := TcxLargeIntValueType;
      ftTimeStamp:
        Result := TcxSQLTimeStampValueType;
    {$ENDIF}
    else
      Result := TcxVariantValueType;
    end;
  end;
end;

{$IFNDEF DELPHI5}

function IsPublishedProp(Instance: TObject; const PropName: string): Boolean;
begin
  Result := GetPropInfo(Instance.ClassInfo, PropName) <> nil;
end;

function GetObjectProp(Instance: TObject; const PropName: string): TObject;
var
  PropInfo: PPropInfo;
begin
  Result := nil;
  PropInfo := TypInfo.GetPropInfo(Instance.ClassInfo, PropName);
  if (PropInfo <> nil) and (PropInfo^.PropType^.Kind = tkClass) then
    Result := TObject(GetOrdProp(Instance, PropInfo));
end;

{$ENDIF}

{ TcxDBProviderDetailFilterAdapter }

function TcxDBProviderDetailFilterAdapter.IsCurrentQuery(ADataSet: TDataSet;
  const AParamNames: string; const AParamValues: Variant): Boolean;
var
  AParams: TParams;
begin
  Result := False;
  if IsPublishedProp(ADataSet, 'Params') then
  begin
    AParams := GetObjectProp(ADataSet, 'Params') as TParams;
    if AParams <> nil then
    begin
      if VarEquals(AParams.ParamValues[AParamNames], AParamValues) then
        Result := True;
    end;
  end;
end;

procedure TcxDBProviderDetailFilterAdapter.ReopenSQL(ADataSet: TDataSet;
  const AParamNames: string; const AParamValues: Variant; var AReopened: Boolean);
var
  AParams: TParams;
begin
  if IsPublishedProp(ADataSet, 'Params') then
  begin
    AParams := GetObjectProp(ADataSet, 'Params') as TParams;
    if AParams <> nil then
    begin
      if VarEquals(AParams.ParamValues[AParamNames], AParamValues) then
        ADataSet.First // TODO: Update method - for Query with Post
      else
      begin
        ADataSet.DisableControls;
        try
          ADataSet.Active := False;
          AParams.ParamValues[AParamNames] := AParamValues;
          ADataSet.Active := True;
        finally
          ADataSet.EnableControls;
        end;
        AReopened := True; // set Flag if Query reopened
      end;
    end;
  end;
end;

procedure TcxDBProviderDetailFilterAdapter.SetFilter(ADataSet: TDataSet;
  const AMasterDetailKeyFieldNames: string; const AMasterDetailKeyValues: Variant;
  AIsSQLMode: Boolean; var AReopened: Boolean);
begin
  if AIsSQLMode then
    ReopenSQL(ADataSet, AMasterDetailKeyFieldNames, AMasterDetailKeyValues, AReopened)
  else
    ADataSet.Locate(AMasterDetailKeyFieldNames, AMasterDetailKeyValues, []); // must be sort by Detail Keys
end;

{ TcxDBDataModeController }

constructor TcxDBDataModeController.Create(ADataController: TcxDBDataController);
begin
  inherited Create;
  FDetailInSyncMode := True;
  FDataController := ADataController;
  FGridModeBufferCount := 0;
  FSyncInsert := True;
  FSyncMode := True;
end;

procedure TcxDBDataModeController.Assign(Source: TPersistent);
begin
  if Source is TcxDBDataModeController then
  begin
    DetailInSQLMode := TcxDBDataModeController(Source).DetailInSQLMode;
    DetailInSyncMode := TcxDBDataModeController(Source).DetailInSyncMode;
    GridMode := TcxDBDataModeController(Source).GridMode;
    GridModeBufferCount := TcxDBDataModeController(Source).GridModeBufferCount;
    SmartRefresh := TcxDBDataModeController(Source).SmartRefresh;
    SyncInsert := TcxDBDataModeController(Source).SyncInsert;
    SyncMode := TcxDBDataModeController(Source).SyncMode;
    OnDetailFirst := TcxDBDataModeController(Source).OnDetailFirst;
    OnDetailIsCurrentQuery := TcxDBDataModeController(Source).OnDetailIsCurrentQuery;
  end
  else
    inherited Assign(Source);
end;

function TcxDBDataModeController.DetailIsCurrentQuery(const AMasterDetailKeyFieldNames: string;
  const AMasterDetailKeyValues: Variant): Boolean;
var
  ADetailFilterAdapter: TcxDBProviderDetailFilterAdapter;
begin
  if Assigned(FOnDetailIsCurrentQuery) then
    Result := FOnDetailIsCurrentQuery(Self, DataController.DataSet,
      AMasterDetailKeyFieldNames, AMasterDetailKeyValues)
  else
  begin
    ADetailFilterAdapter := DataController.GetDetailFilterAdapter;
    Result := ADetailFilterAdapter.IsCurrentQuery(DataController.DataSet,
      AMasterDetailKeyFieldNames, AMasterDetailKeyValues);
  end;
end;

procedure TcxDBDataModeController.DoDetailFirst(const AMasterDetailKeyFieldNames: string;
  const AMasterDetailKeyValues: Variant; var AReopened: Boolean);
var
  ADetailFilterAdapter: TcxDBProviderDetailFilterAdapter;
begin
  AReopened := False;
  if Assigned(FOnDetailFirst) then
    FOnDetailFirst(Self, DataController.DataSet, AMasterDetailKeyFieldNames,
      AMasterDetailKeyValues, AReopened)
  else
  begin
    ADetailFilterAdapter := DataController.GetDetailFilterAdapter;
    ADetailFilterAdapter.SetFilter(DataController.DataSet, AMasterDetailKeyFieldNames,
      AMasterDetailKeyValues, DetailInSQLMode, AReopened);
  end;
end;

procedure TcxDBDataModeController.SetGridMode(Value: Boolean);
var
  APrevGridMode: Boolean;
begin
  APrevGridMode := DataController.IsGridMode;
  if FGridMode <> Value then
  begin
    FGridMode := Value;
    if DataController.IsGridMode <> APrevGridMode then
      DataController.RestructData;
  end;
end;

procedure TcxDBDataModeController.SetGridModeBufferCount(Value: Integer);
begin
  if Value < 0 then Value := 0;
  if FGridModeBufferCount <> Value then
  begin
    FGridModeBufferCount := Value;
    DataController.UpdateGridModeBufferCount;
  end;
end;

procedure TcxDBDataModeController.SetSmartRefresh(Value: Boolean);
begin
  if FSmartRefresh <> Value then
  begin
    FSmartRefresh := Value;
    if not DataController.Provider.IsGridMode then
      DataController.Provider.DataScrolled(0);
  end;
end;

procedure TcxDBDataModeController.SetSyncMode(Value: Boolean);
begin
  if FSyncMode <> Value then
  begin
    FSyncMode := Value;
    if DataController.Provider.IsActive then
      DataController.Provider.DataScrolled(0);
  end;
end;

{ TcxDBDataSelection }

constructor TcxDBDataSelection.Create(ADataController: TcxCustomDataController);
begin
  inherited Create(ADataController);
  FBookmarks := TStringList.Create;
end;

destructor TcxDBDataSelection.Destroy;
begin
  FBookmarks.Free;
  FBookmarks := nil;
  inherited Destroy;
end;

function TcxDBDataSelection.FindByRowIndex(ARowIndex: Integer; var AIndex: Integer): Boolean;
begin
  if DataController.IsGridMode then
    Result := FindBookmark(GetRowBookmark(ARowIndex), AIndex)
  else
    Result := inherited FindByRowIndex(ARowIndex, AIndex);
end;

procedure TcxDBDataSelection.SelectAll;
begin
  if DataController.IsGridMode and Assigned(DataController.DataSet) then
  begin
    with DataController.Provider do
    begin
      Freeze;
      try
        SavePos;
        First;
        InternalClear;
        try
          while not IsEOF do
          begin
            if DataController.CanSelectRow(-1) then
              FBookmarks.Add(DataSet.Bookmark);
            Next;
          end;
          SyncCount;
        except
          FBookmarks.Clear;
          SyncCount;
          raise;
        end;
        RestorePos;
      finally
        Unfreeze;
        Changed;
        DataController.DataControllerInfo.CheckChanges;
        DataController.SyncMasterPos;
      end;
    end;
  end;
end;

procedure TcxDBDataSelection.SelectFromAnchor(AToBookmark: TBookmarkStr; AKeepSelection: Boolean);

  function CheckBookmarks(const ABkm1, ABkm2: TBookmarkStr; ADirectionDown: Boolean): Boolean;
  begin
    Result := False;
    if AKeepSelection or (FBookmarks.Count = 0) then Exit;
    with DataController.Provider do
    begin
      if CompareBookmarks(ABkm1, ABkm2) = 0 then
      begin
        FBookmarks.Clear;
        if DataController.CanSelectRow(-1) then
          FBookmarks.Add(ABkm1);
        Result := True;
      end
      else
        if ADirectionDown then
        begin
          if (FBookmarks.Count > 1) and
            (CompareBookmarks(FBookmarks[FBookmarks.Count - 2], ABkm2) = 0) then // dec last
          begin
            if CompareBookmarks(FBookmarks[0], ABkm1) = 0 then
            begin
              FBookmarks.Delete(FBookmarks.Count - 1);
              Result := True;
            end;
          end
          else
          begin
            DataSet.Bookmark := ABkm2;
            DataSet.Prior;
            if CompareBookmarks(FBookmarks[FBookmarks.Count - 1], DataSet.Bookmark) = 0 then // inc
            begin
              if CompareBookmarks(FBookmarks[0], ABkm1) = 0 then
              begin
                DataSet.Bookmark := ABkm2; // for OnCanSelectRow event
                if DataController.CanSelectRow(-1) then
                  FBookmarks.Add(ABkm2);
                Result := True;
              end;
            end;
          end;
        end
        else
        begin
          if (FBookmarks.Count > 1) and
            (CompareBookmarks(FBookmarks[1], ABkm1) = 0) then // dec top
          begin
            if CompareBookmarks(FBookmarks[FBookmarks.Count - 1], ABkm2) = 0 then
            begin
              FBookmarks.Delete(0);
              Result := True;
            end;
          end
          else
          begin
            DataSet.Bookmark := ABkm1;
            DataSet.Next;
            if CompareBookmarks(FBookmarks[0], DataSet.Bookmark) = 0 then // inc
            begin
              if CompareBookmarks(FBookmarks[FBookmarks.Count - 1], ABkm2) = 0 then
              begin
                DataSet.Bookmark := ABkm1; // for OnCanSelectRow event
                if DataController.CanSelectRow(-1) then
                  FBookmarks.Insert(0, ABkm1);
                Result := True;
              end;  
            end;
          end;
        end;
    end;
  end;

  procedure LoadBookmarks(const ABkm1, ABkm2: TBookmarkStr);
  var
    ABkm: TBookmarkStr;
    ACheckNeeded, AFound: Boolean;
    I, C, AIndex1, AIndex2: Integer;
  begin
    with DataController.Provider do
    begin
      if not AKeepSelection then
        FBookmarks.Clear;
      try
        ACheckNeeded := FBookmarks.Count > 0;
        if ACheckNeeded then
        begin
          FindBookmark(ABkm1, AIndex1);
          FindBookmark(ABkm2, AIndex2);
          if AIndex1 = FBookmarks.Count then
            ACheckNeeded := False;
        end;
        DataSet.Bookmark := ABkm1;
        while not IsEOF do
        begin
          ABkm := DataSet.Bookmark;
          if ACheckNeeded then
          begin
            AFound := False;
            for I := AIndex1 to AIndex2 do
            begin
              if I >= FBookmarks.Count then
                Break;
              C := CompareBookmarks(ABkm, FBookmarks[I]);
              if C < 0 then
              begin
                if DataController.CanSelectRow(-1) then
                  FBookmarks.Insert(I, ABkm);
                Inc(AIndex1);
                Inc(AIndex2);
                AFound := True;
                Break;
              end
              else
                if C = 0 then
                begin
                  Inc(AIndex1);

⌨️ 快捷键说明

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