cxdb.pas

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

PAS
874
字号

{********************************************************************}
{                                                                    }
{       Developer Express Visual Component Library                   }
{       ExpressDataController                                        }
{                                                                    }
{       Copyright (c) 1998-2008 Developer Express Inc.               }
{       ALL RIGHTS RESERVED                                          }
{                                                                    }
{   The entire contents of this file is protected by U.S. and        }
{   International Copyright Laws. Unauthorized reproduction,         }
{   reverse-engineering, and distribution of all or any portion of   }
{   the code contained in this file is strictly prohibited and may   }
{   result in severe civil and criminal penalties and will be        }
{   prosecuted to the maximum extent possible under the law.         }
{                                                                    }
{   RESTRICTIONS                                                     }
{                                                                    }
{   THIS SOURCE CODE AND ALL RESULTING INTERMEDIATE FILES            }
{   (DCU, OBJ, DLL, ETC.) ARE CONFIDENTIAL AND PROPRIETARY TRADE     }
{   SECRETS OF DEVELOPER EXPRESS INC. THE REGISTERED DEVELOPER IS    }
{   LICENSED TO DISTRIBUTE THE EXPRESSDATACONTROLLER AND ALL         }
{   ACCOMPANYING VCL CONTROLS AS PART OF AN EXECUTABLE PROGRAM ONLY. }
{                                                                    }
{   THE SOURCE CODE CONTAINED WITHIN THIS FILE AND ALL RELATED       }
{   FILES OR ANY PORTION OF ITS CONTENTS SHALL AT NO TIME BE         }
{   COPIED, TRANSFERRED, SOLD, DISTRIBUTED, OR OTHERWISE MADE        }
{   AVAILABLE TO OTHER INDIVIDUALS WITHOUT EXPRESS WRITTEN CONSENT   }
{   AND PERMISSION FROM DEVELOPER EXPRESS INC.                       }
{                                                                    }
{   CONSULT THE END USER LICENSE AGREEMENT FOR INFORMATION ON        }
{   ADDITIONAL RESTRICTIONS.                                         }
{                                                                    }
{********************************************************************}

unit cxDB;

{$I cxVer.inc}

interface

uses
  Classes, SysUtils, {$IFDEF DELPHI6}Variants, {$ENDIF} DB,
  cxDataUtils;

type
  { TcxDBAdapterList }

  TDataSetClass = class of TDataSet;

  TcxDBAdapterItem = class
  private
    FDataSetClass: TDataSetClass;
  public
    constructor Create(ADataSetClass: TDataSetClass); virtual;
    property DataSetClass: TDataSetClass read FDataSetClass;
  end;

  TcxDBAdapterItemClass = class of TcxDBAdapterItem;

  TcxDBAdapterList = class
  private
    FItems: TList;
    function GetItem(Index: Integer): TcxDBAdapterItem;
    function GetItemCount: Integer;
  public
    constructor Create;
    destructor Destroy; override;
    procedure Clear;
    function FindAdapter(ADataSetClass: TDataSetClass; var AIndex: Integer): Boolean; virtual;
    procedure RegisterAdapter(ADataSetClass: TDataSetClass; AItemClass: TcxDBAdapterItemClass); virtual;
    procedure UnregisterAdapter(ADataSetClass: TDataSetClass; AItemClass: TcxDBAdapterItemClass); virtual;
    property ItemCount: Integer read GetItemCount;
    property Items[Index: Integer]: TcxDBAdapterItem read GetItem; default;
  end;

  { TcxCustomFieldDataLink }

  TcxCustomDBDataBinding = class;

  TcxCustomFieldDataLink = class(TDataLink)
  private
    FField: TField;
    FFieldName: string;
    FEditing: Boolean;
    FModified: Boolean;
    function GetCanModify: Boolean;
    function GetDataComponent: TComponent;
    procedure SetEditing(Value: Boolean);
    procedure SetField(Value: TField);
    procedure SetFieldName(const Value: string);
    procedure UpdateField;
  protected
    FDataBinding: TcxCustomDBDataBinding;
    procedure ActiveChanged; override;
    procedure DataEvent(Event: TDataEvent; Info: Longint); override;
    procedure EditingChanged; override;
    procedure LayoutChanged; override;
    procedure RecordChanged(Field: TField); override;
    procedure UpdateData; override;
    procedure DataComponentChanged; virtual;
    procedure UpdateRightToLeft; virtual;
    procedure VisualControlChanged; virtual;
    property DataBinding: TcxCustomDBDataBinding read FDataBinding;
    property DataComponent: TComponent read GetDataComponent;
  public
    constructor Create(ADataBinding: TcxCustomDBDataBinding); virtual;
    function Edit: Boolean;
    procedure Modified;
    procedure Reset;
    property CanModify: Boolean read GetCanModify;
    property Editing: Boolean read FEditing;
    property Field: TField read FField;
    property FieldName: string read FFieldName write SetFieldName;
  end;

  TcxCustomFieldDataLinkClass = class of TcxCustomFieldDataLink;

  { TcxCustomDBDataBinding }

  TcxCustomDBDataBinding = class(TcxCustomDataBinding)
  private
    FRefreshCount: Integer;
    function GetDataField: string;
    function GetDataSource: TDataSource;
    function GetField: TField;
    procedure InternalDataChange;
    procedure SetDataField(const Value: string);
    procedure SetDataSource(Value: TDataSource);
  protected
    FDataLink: TcxCustomFieldDataLink;
    function GetModified: Boolean; override;
    function GetReadOnly: Boolean; override;
    procedure SetReadOnly(Value: Boolean); override;
    procedure VisualControlChanged; override;
    procedure DisableRefresh;
    procedure EnableRefresh;
    function GetDataLinkClass: TcxCustomFieldDataLinkClass; virtual;
    function IsRefreshDisabled: Boolean;
  public
    constructor Create(AOwner, ADataComponent: TComponent); override;
    destructor Destroy; override;
    function CanModify: Boolean; override;
    function ExecuteAction(Action: TBasicAction): Boolean; override;
    function GetStoredValue(AValueSource: TcxDataEditValueSource; AFocused: Boolean): Variant; override;
    function IsControlReadOnly: Boolean; override;
    function IsDataSourceLive: Boolean; override;
    function IsDataStorage: Boolean; override;
    procedure Reset; override;
    function SetEditMode: Boolean; override;
    procedure SetStoredValue(AValueSource: TcxDataEditValueSource; const Value: Variant); override;
    function UpdateAction(Action: TBasicAction): Boolean; override;
    procedure UpdateDataSource; override;
    property Field: TField read GetField;
    property DataSource: TDataSource read GetDataSource write SetDataSource;
    property DataField: string read GetDataField write SetDataField;
    property DataLink: TcxCustomFieldDataLink read FDataLink;
  end;

function CanModifyLookupField(AField: TField): Boolean;
procedure CheckFilterFieldName(var AFieldName: string);
function GetDataSetValues(ADataSet: TDataSet; AFields: TList): Variant;
function GetFilterFieldName(AField: TField; AIgnoreOrigin: Boolean): string;
function IsEqualFieldNames(const AFieldName1, AFieldName2: string): Boolean;
function IsFieldCanModify(AField: TField; AIsValueSource: Boolean): Boolean;
function IsFieldFormatted(AField: TField; AIsTextEdit: Boolean): Boolean;
function IsMultipleFieldNames(const AFieldNames: string): Boolean;
function IsSimpleCurrencyField(AField: TField): Boolean;
function GetFieldNamesCount(const AFieldNames: string): Integer;
procedure GetFieldNames(const AFieldNames: string; AList: TStrings);
function GetFieldValue(AField: TField): Variant;
procedure SetDataSetValues(ADataSet: TDataSet; AFields: TList; const AValues: Variant);
procedure SetFieldValue(AField: TField; const AValue: Variant);

implementation

uses
  cxVariants;

function CanModifyLookupField(AField: TField): Boolean;
var
  AMasterFields: TList;
  I: Integer;
begin
  Result := False;
  if Assigned(AField.DataSet) then
  begin
    AMasterFields := TList.Create;
    try
      AField.DataSet.GetFieldList(AMasterFields, AField.KeyFields);
      Result := AMasterFields.Count > 0;
      for I := 0 to AMasterFields.Count - 1 do
        Result := Result and TField(AMasterFields[I]).CanModify;
    finally
      AMasterFields.Free;
    end;
  end;
end;

procedure CheckFilterFieldName(var AFieldName: string);
begin
  if not IsValidIdent(AFieldName) then
    AFieldName := '[' + AFieldName + ']';
end;

function GetDataSetValues(ADataSet: TDataSet; AFields: TList): Variant;
var
  I: Integer;
begin
  if AFields.Count > 0 then
  begin
    if AFields.Count > 1 then
    begin
      Result := VarArrayCreate([0, AFields.Count - 1], varVariant);
      for I := 0 to AFields.Count - 1 do
        Result[I] := TField(AFields[I]).Value;
    end
    else
      Result := TField(AFields[0]).Value;
  end
  else
    Result := Null;
end;

function GetFilterFieldName(AField: TField; AIgnoreOrigin: Boolean): string;
begin
  Result := '';
  if Assigned(AField) then
  begin
    if not AIgnoreOrigin then
      Result := AField.Origin;
    if Result = '' then
    begin
      Result := AField.FieldName;
      CheckFilterFieldName(Result);
    end;
  end;
end;

function IsEqualFieldNames(const AFieldName1, AFieldName2: string): Boolean;
begin
  Result := AnsiUpperCase(AFieldName1) = AnsiUpperCase(AFieldName2);
end;

function IsFieldCanModify(AField: TField; AIsValueSource: Boolean): Boolean;
begin
  Result := AField.CanModify and
    (AIsValueSource or not (AField.DataType in ftNonTextTypes) or Assigned(AField.OnSetText));
end;

function IsFieldFormatted(AField: TField; AIsTextEdit: Boolean): Boolean;
begin
  Result := Assigned(AField.OnGetText) or (AField.EditMask <> '');
  if not Result then
  begin
    if AField.DataType in ftNonTextTypes  then 
      Result := AIsTextEdit // Field.DisplayText!
    else
      if AField is TBooleanField then
        Result := AIsTextEdit // TODO: compare DisplayValues
      else
        if AField is TNumericField then
        begin
          Result := ((AField as TNumericField).DisplayFormat <> '') or
            ((AField as TNumericField).EditFormat <> '');
          if not Result then
          begin
            if AField is TFloatField then
              Result := (AField as TFloatField).Currency
            else
              if AField is TBCDField then
                Result := (AField as TBCDField).Currency
              {$IFDEF DELPHI6}
              else
                if AField is TFMTBCDField then
                  Result := (AField as TFMTBCDField).Currency
              {$ENDIF}
          end;
        end
        else
          if AField is TDateTimeField then
            Result := (AField as TDateTimeField).DisplayFormat <> ''
          else
            {$IFDEF DELPHI5}
            if AField is TAggregateField then
              Result := ((AField as TAggregateField).DisplayFormat <> '') or
                (AField as TAggregateField).Currency
            else
              {$IFDEF DELPHI6}
              if AField is TSQLTimeStampField then
                Result := (AField as TSQLTimeStampField).DisplayFormat <> '';
              {$ENDIF}
            {$ENDIF}
  end;
end;

function IsMultipleFieldNames(const AFieldNames: string): Boolean;
var
  APos: Integer;
begin
  APos := 1;
{$WARNINGS OFF}
  ExtractFieldName(AFieldNames, APos);
{$WARNINGS ON}
  Result := APos <= Length(AFieldNames);
end;

function IsSimpleCurrencyField(AField: TField): Boolean;
begin
  Result := False;
  if AField is TNumericField then
  begin
    if AField is TFloatField then
      Result := (AField as TFloatField).Currency
    else
    begin
      if AField is TBCDField then
        Result := (AField as TBCDField).Currency
      {$IFDEF DELPHI6}
      else
        if AField is TFMTBCDField then
          Result := (AField as TFMTBCDField).Currency;
      {$ENDIF}
    end;
    if Result then
    begin
      if ((AField as TNumericField).DisplayFormat <> '') or Assigned(AField.OnGetText) then
        Result := False;
    end;
  end;
end;

function GetFieldNamesCount(const AFieldNames: string): Integer;
var
  APos: Integer;
begin
  Result := 0; // TODO: use GetFieldNames?
  APos := 1;
  while APos <= Length(AFieldNames) do
  begin
    Inc(Result);
  {$WARNINGS OFF}
    ExtractFieldName(AFieldNames, APos);
  {$WARNINGS ON}
  end;
end;

procedure GetFieldNames(const AFieldNames: string; AList: TStrings);
var
  APos: Integer;
begin
  AList.Clear;
  APos := 1;
  while APos <= Length(AFieldNames) do
  {$WARNINGS OFF}
    AList.Add(ExtractFieldName(AFieldNames, APos))
  {$WARNINGS ON}
end;

function GetFieldValue(AField: TField): Variant;
begin
  if AField is TAggregateField then // bug in Delphi (IsNull = True!)
    Result := AField.Value
  else
    if AField.IsNull then
      Result := Null
    else
    begin
    {$IFDEF DELPHI5}
      if AField is TWideStringField then // bug in Delphi
        Result := TWideStringField(AField).Value
      else
    {$ENDIF}  
        Result := AField.Value;
    end;
end;

procedure SetDataSetValues(ADataSet: TDataSet; AFields: TList;
  const AValues: Variant);
var
  I: Integer;
begin
  if AFields.Count > 0 then
  begin
    if AFields.Count > 1 then
    begin
      for I := 0 to AFields.Count - 1 do
        TField(AFields[I]).Value := AValues[I];
    end
    else
      TField(AFields[0]).Value := AValues;
  end;
end;

procedure SetFieldValue(AField: TField; const AValue: Variant);
begin
  if (AField is TDateTimeField) and (VarType(AValue) = varDouble) then // bug in Delphi
    TDateTimeField(AField).Value := AValue
  else
    AField.Value := AValue;
end;

{ TcxDBAdapterItem }

constructor TcxDBAdapterItem.Create(ADataSetClass: TDataSetClass);
begin
  inherited Create;
  FDataSetClass := ADataSetClass;
end;

{ TcxDBAdapterList }

constructor TcxDBAdapterList.Create;
begin
  inherited Create;
  FItems := TList.Create;
end;

destructor TcxDBAdapterList.Destroy;
begin
  Clear;
  FItems.Free;
  FItems := nil;
  inherited Destroy;
end;

procedure TcxDBAdapterList.Clear;
var
  I: Integer;
begin
  for I := 0 to FItems.Count - 1 do
    TObject(FItems[I]).Free;
  FItems.Clear;
end;

function TcxDBAdapterList.FindAdapter(ADataSetClass: TDataSetClass;
  var AIndex: Integer): Boolean;

⌨️ 快捷键说明

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