Ver código fonte

+ Added missing TDatasource support

michael 25 anos atrás
pai
commit
475afa3aac
4 arquivos alterados com 789 adições e 32 exclusões
  1. 121 24
      fcl/db/dataset.inc
  2. 494 0
      fcl/db/datasource.inc
  3. 147 3
      fcl/db/db.pp
  4. 27 5
      fcl/db/dbs.inc

+ 121 - 24
fcl/db/dataset.inc

@@ -27,6 +27,7 @@ begin
   Inherited Create(AOwner);
   FFieldDefs:=TFieldDefs.Create(Self);
   FFieldList:=TFields.Create(Self);
+  FDataSources:=TList.Create;
 end;
 
 
@@ -37,6 +38,12 @@ begin
   Active:=False;
   FFieldDefs.Free;
   FFieldList.Free;
+  With FDatasources do
+    begin
+    While Count>0 do
+      TDatasource(Items[Count]).DataSet:=Nil;
+    Free;  
+    end;  
   Inherited Destroy;
 end;
 
@@ -143,8 +150,27 @@ end;
 
 Procedure TDataset.DataEvent(Event: TDataEvent; Info: Longint);
 
+Var 
+  i : longint;
+
 begin
-  //!! To be implemented
+  // Do some bookkeeping;
+  case Event of
+    deFieldChange :
+      begin
+      if TField(Info).FieldKind in [fkData,fkInternalCalc] then
+        SetModified(True);
+      if FInternalCalcFields and (TField(Info).FieldKind = fkData) then
+          RefreshInternalCalcFields(ActiveBuffer)
+      else if (FCalcFieldsSize <> 0) and FAutoCalcFields and
+        (TField(Info).FieldKind = fkData) then
+        CalculateFields(ActiveBuffer);
+      TField(Info).Change;
+      end;  
+  end;
+  // Distribute event to datasets;    
+  for I := 0 to FDataSources.Count - 1 do
+    TDataSource(FDataSources[I]).ProcessEvent(Event, Info);
 end;
 
 Procedure TDataset.DestroyFields;
@@ -775,6 +801,7 @@ begin
   If Value<>FState then
     begin
     FState:=Value;
+    DataEvent(deUpdateState,0);
     end;
 end;
 
@@ -840,6 +867,7 @@ Procedure TDataset.Cancel;
 begin
   If State in [dsEdit,dsInsert] then
     begin
+    DataEvent(deCheckBrowseMode,0);  
     DoBeforeCancel;
     UpdateCursorPos;
     InternalCancel;
@@ -854,6 +882,7 @@ Procedure TDataset.CheckBrowseMode;
 
 begin
   CheckActive;
+  DataEvent(deCheckBrowseMode,0);
   If State In [dsedit,dsinsert] then
     begin
     UpdateRecord;
@@ -908,7 +937,15 @@ Procedure TDataset.DisableControls;
 
 
 begin
-  //!! To be implemented
+  If FDisableControlsCount=0 then
+    begin
+    { Save current state, 
+      needed to detect change of state when enabling controls.
+    }  
+    FDisableControlsState:=FState;
+    FEnableControlsEvent:=deDatasetChange;
+    end;
+  Inc(FDisableControlsCount);  
 end;
 
 Procedure TDataset.DoInsertAppend(DoAppend : Boolean);
@@ -972,6 +1009,7 @@ begin
   // mark as not modified.
   FModified:=False;
   // Final events.
+  DataEvent(deDatasetChange,0);
   DoAfterInsert;
   DoAfterScroll;
   {$ifdef dsdebug}
@@ -995,6 +1033,7 @@ begin
   If Not TryDoing(@InternalEdit,OnEditError) then
     exit;
   SetState(dsedit);
+  DataEvent(deRecordChange,0);
   DoAfterEdit;
 end;
 
@@ -1002,7 +1041,18 @@ Procedure TDataset.EnableControls;
 
 
 begin
-  //!! To be implemented
+  If FDisableControlsCount>0 then
+    begin
+    Dec(FDisableControlsCount);
+    If FDisableControlsCount=0 then
+      begin
+      // State changed since disablecontrols ?
+      If FDisableControlsState<>FState then 
+        DataEvent(deUpdateState,0);
+      If (FDisableControlsState<>dsInactive) and (FState<>dsInactive) then
+        DataEvent(FEnableControlsEvent,0);
+      end;
+    end;    
 end;
 
 Function TDataset.FieldByName(const FieldName: string): TField;
@@ -1061,6 +1111,7 @@ begin
     GetNextRecords;
   finally
     FBOF:=True;
+    DataEvent(deDatasetChange,0);
     DoAfterScroll;
   end;
 end;
@@ -1157,15 +1208,17 @@ begin
     FActiveRecord:=FRecordCount-1;
   finally
     FEOF:=true;
+    DataEvent(deDataSetChange, 0);
     DoAfterScroll;
   end;
 end;
 
 Function TDataset.MoveBy(Distance: Longint): Longint;
 
-  Procedure Scrollforward;
+  Function Scrollforward : Integer;
 
   begin
+    Result:=0;
 {$ifdef dsdebug}
     Writeln('Scrolling forward :',Distance);
     Writeln('Active buffer : ',FActiveRecord);
@@ -1176,25 +1229,29 @@ Function TDataset.MoveBy(Distance: Longint): Longint;
       If FActiveRecord<FRecordCount-1 then
         begin
         Inc(FActiveRecord);
-        Dec(Distance)
+        Dec(Distance);
+        Inc(Result);
         end
       else
         begin
        {$ifdef dsdebug}
-           Writeln('Moveby : need next record');
+       Writeln('Moveby : need next record');
        {$endif}
         If GetNextRecord then
-          Dec(Distance)
+          begin
+          Dec(Distance);
+          Inc(result);
+          end
         else
           FEOF:=true;
         end;
       end
   end;
 
-  Procedure ScrollBackward;
+  Function ScrollBackward : Integer;
 
   begin
-
+    Result:=0;
 {$ifdef dsdebug}
     Writeln('Scrolling backward:',Abs(Distance));
     Writeln('Active buffer : ',FActiveRecord);
@@ -1205,34 +1262,47 @@ Function TDataset.MoveBy(Distance: Longint): Longint;
       If FActiveRecord>0 then
         begin
         Dec(FActiveRecord);
-        Inc(Distance)
+        Inc(Distance);
+        Dec(Result);
         end
       else
         begin
        {$ifdef dsdebug}
-           Writeln('Moveby : need next record');
+       Writeln('Moveby : need next record');
        {$endif}
         If GetPriorRecord then
-          Inc(Distance)
+          begin
+          Inc(Distance);
+          Dec(Result);
+          end
         else
           FBOF:=true;
         end;
       end
   end;
 
+Var 
+  PrevRecordCount : Integer; 
+  Scrolled : Integer;
+  
 begin
   CheckBrowseMode;
   Result:=0;
+  PrevRecordCount:=0;
   DoBeforeScroll;
   If ((Distance>0) and FEOF) or
      ((Distance<0) and FBOF) then
     exit;
   Try
     If Distance>0 then
-      ScrollForward
+      Scrolled:=ScrollForward
     else
-      ScrollBackward;
+      Scrolled:=ScrollBackward;
   finally
+     If FRecordCount<>PrevRecordCount then
+       DataEvent(deDatasetChange,0)
+     else
+       DataEvent(deDatasetScroll,Scrolled);
      DoAfterScroll;
   end;
 end;
@@ -1267,6 +1337,7 @@ Procedure TDataset.Post;
 begin
   if State in [dsEdit,dsInsert] then
     begin
+    DataEvent(deCheckBrowseMode,0);
 {$ifdef dsdebug}
     writeln ('Post: checking required fields');
 {$endif}
@@ -1304,6 +1375,13 @@ begin
   Resync([]);
 end;
 
+Procedure TDataset.RegisterDataSource(ADatasource : TDataSource);
+
+begin
+  FDatasources.Add(ADataSource);
+end;
+
+
 Procedure TDataset.Resync(Mode: TResyncMode);
 
 Var Count,ShiftCount : Longint;
@@ -1326,6 +1404,7 @@ begin
        begin
        // nothing found, invalidate buffer and bail out.
        ClearBuffers;
+       DataEvent(deDatasetChange,0);
        Exit;
        end;
   If (rmCenter in Mode) then
@@ -1336,14 +1415,21 @@ begin
   // Reposition on 0
   ShiftBuffers(0,FRecordCount-1);
   ActivateBuffers;
-  Count:=0;
-  Writeln ('Getting previous',ShiftCount,' records');
-  While (Count<ShiftCount) and GetPriorRecord do Inc(Count);
-  FActiveRecord:=Count;
-  // fill rest of buffers, adjust ActiveBuffer.
-  SetCurrentRecord(FRecordCount-1);
-  GetNextRecords;
-  Inc(FActiveRecord,GetPriorRecords);
+  try
+    Count:=0;
+    {$ifdef dsdebug}
+    Writeln ('Getting previous',ShiftCount,' records');
+    {$endif}  
+    While (Count<ShiftCount) and GetPriorRecord do Inc(Count);
+    FActiveRecord:=Count;
+    // fill rest of buffers, adjust ActiveBuffer.
+    SetCurrentRecord(FRecordCount-1);
+    GetNextRecords;
+    Inc(FActiveRecord,GetPriorRecords);
+  finally
+    // Notify Everyone
+    DataEvent(deDatasetChange,0);
+  end;  
 end;
 
 Procedure TDataset.SetFields(const Values: array of const);
@@ -1415,7 +1501,8 @@ end;
 Procedure TDataset.UpdateRecord;
 
 begin
-  //!! To be implemented
+  if not (State in dsEditModes) then DatabaseError(SNotInEditState, Self);
+  DataEvent(deUpdateRecord, 0); 
 end;
 
 Procedure TDataset.RemoveField (Field : TField);
@@ -1473,9 +1560,19 @@ begin
   end;
 end;
 
+Procedure TDataset.UnRegisterDataSource(ADatasource : TDatasource);
+
+begin
+  FDataSources.Remove(ADataSource);
+end;
+
+
 {
   $Log$
-  Revision 1.1.2.1  2000-08-05 18:22:29  peter
+  Revision 1.1.2.2  2000-12-23 10:10:21  michael
+  + Added missing TDatasource support
+
+  Revision 1.1.2.1  2000/08/05 18:22:29  peter
     * removed comment level 2 warnings
 
   Revision 1.1  2000/07/13 06:31:27  michael

+ 494 - 0
fcl/db/datasource.inc

@@ -0,0 +1,494 @@
+{ ---------------------------------------------------------------------
+    TDatalink
+  ---------------------------------------------------------------------}
+
+Constructor TDataLink.Create;
+
+begin
+  Inherited Create;
+  FBufferCount:=1;
+  FDatasourceFixed:=False;
+end;
+
+
+Destructor TDataLink.Destroy; 
+
+begin
+  Factive:=False;
+  FEditing:=False;
+  FDataSourceFixed:=False;
+  DataSource:=Nil;
+  Inherited Destroy;
+end;
+
+  
+Procedure TDataLink.ActiveChanged; 
+
+begin
+end;
+
+Procedure TDataLink.CheckActiveAndEditing;
+
+Var
+  B : Boolean;
+
+begin
+  B:=Assigned(DataSource) and (DataSource.State<>dsInactive);
+  If B<>FActive then
+    begin
+    FActive:=B;
+    ActiveChanged;
+    end;
+  B:=Assigned(DataSource) and (DataSource.State in dsEditModes) and Not FReadOnly;
+  If B<>FEditing Then
+    begin
+    FEditing:=B;
+    EditingChanged;
+    end;
+end;
+
+
+Procedure TDataLink.CheckBrowseMode; 
+
+begin
+end;
+
+Function TDataLink.CalcFirstRecord(Index : Integer) : Integer;
+
+{ recalculates index of first record in buffer, 
+  and returns number of record scrolled.}
+
+Var 
+   A,              // Index of active record in buffer
+   F,              // Index of current first record in buffer 
+   L : Integer;    // index of Last (for us) record in buffer;
+ 
+begin
+  A:=DataSource.DataSet.FActiveRecord;
+  F:=FFirstRecord+Index;
+  L:=F+FBufferCount-1;
+  If A>L Then
+    Result:=A-L
+  else If A<F Then
+    Result:=A-F;
+  FFirstRecord:=F+Result;
+end;
+
+
+Procedure TDataLink.DataEvent(Event: TDataEvent; Info: Longint); 
+
+
+begin
+  Case Event of
+    deFieldChange, 
+    deRecordChange : 
+      If Not FUpdatingRecord then
+        RecordChanged(TField(Info));
+    deDataSetChange: 
+      begin
+      CalcFirstRecord(Info);
+      DatasetChanged;
+      end;
+    deDataSetScroll: 
+      DatasetScrolled(CalcFirstRecord(Info));
+    deLayoutChange: 
+      begin
+      CalcFirstRecord(Info);
+      LayoutChanged;
+      end;
+    deUpdateRecord: 
+      UpdateRecord;
+    deUpdateState: 
+      CheckActiveAndEditing;
+    deCheckBrowseMode:
+      CheckBrowseMode;
+    deFocusControl: 
+      FocusControl(TFieldRef(Info));
+  end;     
+end;
+
+
+Procedure TDataLink.DataSetChanged; 
+
+begin
+  RecordChanged(Nil);
+end;
+
+
+Procedure TDataLink.DataSetScrolled(Distance: Integer); 
+
+begin
+  DataSetChanged;
+end;
+
+
+Procedure TDataLink.EditingChanged; 
+
+begin
+end;
+
+
+Procedure TDataLink.FocusControl(Field: TFieldRef); 
+
+begin
+end;
+
+
+Function TDataLink.GetActiveRecord: Integer; 
+
+begin
+  Result:=Dataset.FActiveRecord;
+end;
+
+Function TDatalink.GetDataSet : TDataset;
+
+begin
+  Result:=FDataSource.DataSet
+end;
+
+
+Function TDataLink.GetBOF: Boolean; 
+
+begin
+  Result:=DataSet.BOF
+end;
+
+
+Function TDataLink.GetBufferCount: Integer; 
+
+begin
+  Result:=FBufferCount;
+end;
+
+
+Function TDataLink.GetEOF: Boolean; 
+
+begin
+  Result:=DataSet.EOF
+end;
+
+
+Function TDataLink.GetRecordCount: Integer; 
+
+Var D : TDataSet;
+
+begin
+  Result:=Dataset.RecordCount;
+  If Result>BufferCount then
+    Result:=BufferCount;
+end;
+
+
+Procedure TDataLink.LayoutChanged; 
+
+begin
+  DataSetChanged;
+end;
+
+
+Function TDataLink.MoveBy(Distance: Integer): Integer; 
+
+begin
+  DataSet.MoveBy(Distance);
+end;
+
+
+Procedure TDataLink.RecordChanged(Field: TField); 
+
+begin
+end;
+
+
+Procedure TDataLink.SetActiveRecord(Value: Integer); 
+
+begin
+  Dataset.FActiveRecord:=Value;
+end;
+
+
+Procedure TDataLink.SetBufferCount(Value: Integer); 
+
+begin
+  If FBUfferCount<>Value then
+    begin
+    FBufferCount:=Value;
+    Dataset.SetBufListSize(Value);
+    end;
+end;
+
+Procedure TDataLink.SetDataSource(Value : TDatasource);
+
+begin
+  If Not FDataSourceFixed then
+    begin
+    If FDatasource<>Nil then
+      FDataSource.UnRegisterDatalink(Self);
+    FDataSource:=Value;
+    FDataSource.RegisterDatalink(Self);
+    end;
+end;
+
+Procedure TDatalink.SetReadOnly(Value : Boolean); 
+
+begin
+  If FReadOnly<>Value then
+    begin
+    FReadOnly:=Value;
+    CheckActiveAndEditing;
+    end;
+end;
+
+Procedure TDataLink.UpdateData; 
+
+begin
+end;
+
+
+
+Function TDataLink.Edit: Boolean;
+
+begin
+  If Not FReadOnly then
+    DataSource.Edit;
+  // Triggered event will set FEditing
+  Result:=FEditing;  
+end;
+
+
+Procedure TDataLink.UpdateRecord;
+
+begin
+  FUpdatingRecord:=True;
+  Try
+    UpdateData;
+  finally
+   FUpdatingRecord:=False;
+  end;
+end;
+
+
+
+{ ---------------------------------------------------------------------
+    TDetailDataLink
+  ---------------------------------------------------------------------}
+  
+Function TDetailDataLink.GetDetailDataSet: TDataSet; 
+
+begin
+end;
+
+
+{ ---------------------------------------------------------------------
+    TMasterDataLink
+  ---------------------------------------------------------------------}
+
+constructor TMasterDataLink.Create(ADataSet: TDataSet);
+
+begin
+end;
+
+
+destructor TMasterDataLink.Destroy; 
+
+begin
+end;
+  
+
+Procedure TMasterDataLink.ActiveChanged; 
+
+begin
+end;
+
+
+Procedure TMasterDataLink.CheckBrowseMode; 
+
+begin
+end;
+
+
+Function TMasterDataLink.GetDetailDataSet: TDataSet; 
+
+begin
+end;
+
+
+Procedure TMasterDataLink.LayoutChanged; 
+
+begin
+end;
+
+
+Procedure TMasterDataLink.RecordChanged(Field: TField); 
+
+begin
+end;
+
+procedure TMasterDatalink.SetFieldNames(const Value: string);
+
+begin
+end;
+
+
+{ ---------------------------------------------------------------------
+    TDatasource
+  ---------------------------------------------------------------------}
+    
+Constructor TDataSource.Create(AOwner: TComponent); 
+
+begin
+  Inherited Create(AOwner);
+  FDatalinks:=TList.Create;
+  FEnabled:=True;
+  FAutoEdit:=True;
+end;
+
+
+Destructor TDataSource.Destroy; 
+
+begin
+  FOnStateCHange:=Nil;
+  Dataset:=Nil;
+  With FDataLinks do 
+    While Count>0 do
+      TDatalink(Items[Count]).DataSource:=Nil;
+  FDatalinks.Free;
+end;
+
+
+Procedure TDatasource.Edit;
+
+begin
+  If (State=dsBrowse) and AutoEdit Then
+    Dataset.Edit;
+end;
+
+
+Function TDataSource.IsLinkedTo(ADataSet: TDataSet): Boolean;
+
+begin
+  Result:=False;
+end;
+
+
+procedure TDatasource.DistributeEvent(Event: TDataEvent; Info: Longint);
+
+
+Var 
+  i : Longint;
+
+begin
+  With FDatalinks do
+    begin
+    For I:=0 to Count-1 do
+      With TDatalink(Items[i]) do
+        If Not VisualControl Then
+          DataEvent(Event,Info); 
+    For I:=0 to Count-1 do
+      With TDatalink(Items[i]) do
+        If VisualControl Then
+          DataEvent(Event,Info); 
+    end;
+end;
+
+procedure TDatasource.RegisterDataLink(DataLink: TDataLink);
+
+begin
+  FDatalinks.Add(DataLink);
+  If DataSet<>Nil then 
+    Dataset.SetBufListSize(Datalink.BufferCount);
+end;
+
+
+procedure TDatasource.SetDataSet(ADataSet: TDataSet);
+
+begin
+  If FDataset<>Nil Then
+    FDataset.UnRegisterDataSource(Self);
+  If ADataset<>Nil Then
+    ADataset.RegisterDatasource(Self);
+  FDataSet:=ADAtaset;  
+  ProcessEvent(deUpdateState,0);
+end;
+
+
+procedure TDatasource.SetEnabled(Value: Boolean);
+
+begin
+  FEnabled:=Value;
+end;
+
+
+Procedure TDatasource.DoDataChange (Info : Pointer);
+
+begin
+  If Assigned(OnDataChange) Then
+    OnDataChange(Self,TField(Info));
+end;
+
+Procedure TDatasource.DoStateChange;
+
+begin
+  If Assigned(OnStateChange) Then 
+    OnStateChange(Self);
+end;
+
+
+Procedure TDatasource.DoUpdateData;
+
+begin
+  If Assigned(OnUpdateData) Then 
+    OnUpdateData(Self);
+end;
+
+
+procedure TDatasource.UnregisterDataLink(DataLink: TDataLink);
+
+begin
+  FDatalinks.Remove(Datalink);
+  If Dataset<>Nil then 
+    Dataset.SetBufListSize(DataLink.BufferCount);
+end;
+
+
+procedure TDataSource.ProcessEvent(Event : TDataEvent; Info : longint);
+
+Const 
+  OnDataChangeEvents = [deRecordChange, deDataSetChange, 
+                           deDataSetScroll, 
+                           deLayoutChange,deUpdateState];
+
+Var
+  NeedDataChange : Boolean;
+  FLastState : TdataSetState;
+  
+begin
+  // Special UpdateState handling.
+  If Event=deUpdateState then
+    begin
+    NeedDataChange:=(FState=dsInactive);
+    FLastState:=FState;
+    If Assigned(Dataset) then
+      FState:=Dataset.State
+    else
+      FState:=dsInactive;  
+    // Don't do events if nothing changed.  
+    If FState<>FlastState then 
+      exit;  
+    end
+  else
+    NeedDataChange:=True;  
+  DistributeEvent(Event,Info);
+  // Extra handlers
+  If Not (csDestroying in ComponentState) then
+    begin
+    If (Event=deUpdateState) then
+      DoStateChange;
+    If (Event in OnDataChangeEvents) and 
+       NeedDataChange Then
+      DoDataChange(Nil);
+    If (Event = deFieldChange) Then
+      DoDataCHange(Pointer(Info));
+    If (Event=deUpdateRecord) then
+      DoUpdateData;
+    end;
+ end;

+ 147 - 3
fcl/db/db.pp

@@ -43,6 +43,7 @@ type
   TDataSetState = (dsInactive, dsBrowse, dsEdit, dsInsert, dsSetKey,
     dsCalcFields, dsFilter, dsNewValue, dsOldValue, dsCurValue);
 
+
   TDataEvent = (deFieldChange, deRecordChange, deDataSetChange,
     deDataSetScroll, deLayoutChange, deUpdateRecord, deUpdateState,
     deCheckBrowseMode, dePropertyChange, deFieldListChange, deFocusControl);
@@ -57,7 +58,9 @@ type
   TFields = Class;
   TDataSet = class;
   TDataBase = Class;
-
+  TDatasource = Class;
+  TDatalink = Class;
+  
 { Exception classes }
 
   EDatabaseError = class(Exception);
@@ -749,9 +752,13 @@ type
     FCalcFieldsSize: Longint;
     FCanModify: Boolean;
     FConstraints: TCheckConstraints;
+    FDisableControlsCount : Integer;
+    FDisableControlsState : TDatasetState;
     FCurrentRecord: Longint;
+    FDataSources : TList;
     FDefaultFields: Boolean;
     FEOF: Boolean;
+    FEnableControlsEvent : TDataEvent;
     FFieldList : TFields;
     FFieldCount : Longint;
     FFieldDefs: TFieldDefs;
@@ -770,17 +777,19 @@ type
     FRecNo: Longint;
     FRecordCount: Longint;
     FRecordSize: Word;
-    FState: TDataSetState;
+    FState : TDataSetState;
     Procedure DoInsertAppend(DoAppend : Boolean);
     Procedure DoInternalOpen;
     Procedure DoInternalClose;
     Function  GetBuffer (Index : longint) : Pchar;
     Function  GetField (Index : Longint) : TField;
+    Procedure RegisterDataSource(ADatasource : TDataSource);
     Procedure RemoveField (Field : TField);
     Procedure SetActive (Value : Boolean);
     Procedure SetField (Index : Longint;Value : TField);
     Procedure ShiftBuffers (Offset,Distance : Longint);
     Function  TryDoing (P : TDataOperation; Ev : TDatasetErrorEvent) : Boolean;
+    Procedure UnRegisterDataSource(ADatasource : TDatasource);
     Procedure UpdateFieldDefs;
   protected
     procedure ActivateBuffers; virtual;
@@ -982,6 +991,135 @@ type
     property OnPostError: TDataSetErrorEvent read FOnPostError write FOnPostError;
   end;
 
+  TDataLink = class(TPersistent)
+  private
+    FFIrstRecord,
+    FBufferCount : Integer;
+    FActive,
+    FDataSourceFixed,
+    FEditing,
+    FReadOnly,
+    FUpdatingRecord,
+    FVisualControl : Boolean;
+    FDataSource : TDataSource;
+    Function  CalcFirstRecord(Index : Integer) : Integer;
+    Procedure CheckActiveAndEditing;
+    Function  GetDataset : TDataset;
+    procedure SetDataSource(Value : TDatasource);
+    Procedure SetReadOnly(Value : Boolean);
+  protected
+    procedure ActiveChanged; virtual;
+    procedure CheckBrowseMode; virtual;
+    procedure DataEvent(Event: TDataEvent; Info: Longint); virtual;
+    procedure DataSetChanged; virtual;
+    procedure DataSetScrolled(Distance: Integer); virtual;
+    procedure EditingChanged; virtual;
+    procedure FocusControl(Field: TFieldRef); virtual;
+    function  GetActiveRecord: Integer; virtual;
+    function  GetBOF: Boolean; virtual;
+    function  GetBufferCount: Integer; virtual;
+    function  GetEOF: Boolean; virtual;
+    function  GetRecordCount: Integer; virtual;
+    procedure LayoutChanged; virtual;
+    function  MoveBy(Distance: Integer): Integer; virtual;
+    procedure RecordChanged(Field: TField); virtual;
+    procedure SetActiveRecord(Value: Integer); virtual;
+    procedure SetBufferCount(Value: Integer); virtual;
+    procedure UpdateData; virtual;
+    property VisualControl: Boolean read FVisualControl write FVisualControl;
+  public
+    constructor Create;
+    destructor Destroy; override;
+    function  Edit: Boolean;
+    procedure UpdateRecord;
+    property Active: Boolean read FActive;
+    property ActiveRecord: Integer read GetActiveRecord write SetActiveRecord;
+    property BOF: Boolean read GetBOF;
+    property BufferCount: Integer read FBufferCount write SetBufferCount;
+    property DataSet: TDataSet read GetDataSet;
+    property DataSource: TDataSource read FDataSource write SetDataSource;
+    property DataSourceFixed: Boolean read FDataSourceFixed write FDataSourceFixed;
+    property Editing: Boolean read FEditing;
+    property Eof: Boolean read GetEOF;
+    property ReadOnly: Boolean read FReadOnly write SetReadOnly;
+    property RecordCount: Integer read GetRecordCount;
+  end;
+
+{ TDetailDataLink }
+
+  TDetailDataLink = class(TDataLink)
+  protected
+    function GetDetailDataSet: TDataSet; virtual;
+  public
+    property DetailDataSet: TDataSet read GetDetailDataSet;
+  end;
+
+{ TMasterDataLink }
+
+  TMasterDataLink = class(TDetailDataLink)
+  private
+    FDataSet: TDataSet;
+    FFieldNames: string;
+    FFields: TList;
+    FOnMasterChange: TNotifyEvent;
+    FOnMasterDisable: TNotifyEvent;
+    procedure SetFieldNames(const Value: string);
+  protected
+    procedure ActiveChanged; override;
+    procedure CheckBrowseMode; override;
+    function GetDetailDataSet: TDataSet; override;
+    procedure LayoutChanged; override;
+    procedure RecordChanged(Field: TField); override;
+  public
+    constructor Create(ADataSet: TDataSet);
+    destructor Destroy; override;
+    property FieldNames: string read FFieldNames write SetFieldNames;
+    property Fields: TList read FFields;
+    property OnMasterChange: TNotifyEvent read FOnMasterChange write FOnMasterChange;
+    property OnMasterDisable: TNotifyEvent read FOnMasterDisable write FOnMasterDisable;
+  end;
+
+{ TDataSource }
+
+  TDataChangeEvent = procedure(Sender: TObject; Field: TField) of object;
+
+  TDataSource = class(TComponent)
+  private
+    FDataSet: TDataSet;
+    FDataLinks: TList;
+    FEnabled: Boolean;
+    FAutoEdit: Boolean;
+    FState: TDataSetState;
+    FOnStateChange: TNotifyEvent;
+    FOnDataChange: TDataChangeEvent;
+    FOnUpdateData: TNotifyEvent;
+    procedure DistributeEvent(Event: TDataEvent; Info: Longint);
+    procedure RegisterDataLink(DataLink: TDataLink);
+    Procedure ProcessEvent(Event : TDataEvent; Info : longint);
+    procedure SetDataSet(ADataSet: TDataSet);
+    procedure SetEnabled(Value: Boolean);
+    procedure UnregisterDataLink(DataLink: TDataLink);
+  protected
+    Procedure DoDataChange (Info : Pointer);virtual;
+    Procedure DoStateChange; virtual;
+    Procedure DoUpdateData;
+    property DataLinks: TList read FDataLinks;
+  public
+    constructor Create(AOwner: TComponent); override;
+    destructor Destroy; override;
+    procedure Edit;
+    function IsLinkedTo(ADataSet: TDataSet): Boolean;
+    property State: TDataSetState read FState;
+  published
+    property AutoEdit: Boolean read FAutoEdit write FAutoEdit default True;
+    property DataSet: TDataSet read FDataSet write SetDataSet;
+    property Enabled: Boolean read FEnabled write SetEnabled default True;
+    property OnStateChange: TNotifyEvent read FOnStateChange write FOnStateChange;
+    property OnDataChange: TDataChangeEvent read FOnDataChange write FOnDataChange;
+    property OnUpdateData: TNotifyEvent read FOnUpdateData write FOnUpdateData;
+  end;
+
+
  { TDBDataset }
 
   TDBDatasetClass = Class of TDBDataset;
@@ -1069,6 +1207,8 @@ Const
       'TypedBinary',
       'Cursor'
     );
+
+   dsEditModes = [dsEdit, dsInsert];
 { Auxiliary functions }
 
 Procedure DatabaseError (Const Msg : String);
@@ -1254,13 +1394,17 @@ end;
 
 {$i dataset.inc}
 {$i fields.inc}
+{$i datasource.inc}
 {$i database.inc}
 
 end.
 
 {
   $Log$
-  Revision 1.1.2.1  2000-08-05 14:39:16  michael
+  Revision 1.1.2.2  2000-12-23 10:10:22  michael
+  + Added missing TDatasource support
+
+  Revision 1.1.2.1  2000/08/05 14:39:16  michael
   + Changes in streaming applied here too
 
   Revision 1.1  2000/07/13 06:31:27  michael

+ 27 - 5
fcl/db/dbs.inc

@@ -42,10 +42,32 @@ Const
   SNoSuchRecord = 'Could not find the requested record.';  
   SDatasetReadOnly = 'Dataset is read-only.';
   SNeedField = 'Field %s is required, but not supplied.';
-  
+  SNotInEditState = 'Operation not allowed, dataset "%s" is not in an edit state.';  
 {
   $Log$
-  Revision 1.2  2000-07-13 11:32:56  michael
-  + removed logs
- 
-}
+  Revision 1.1.2.1  2000-12-23 10:10:22  michael
+  + Added missing TDatasource support
+
+  Revision 1.1  2000/07/13 06:31:27  michael
+  + Initial import
+
+  Revision 1.7  2000/01/07 01:24:32  peter
+    * updated copyright to 2000
+
+  Revision 1.6  2000/01/06 01:20:32  peter
+    * moved out of packages/ back to topdir
+
+  Revision 1.1  2000/01/03 19:33:06  peter
+    * moved to packages dir
+
+  Revision 1.4  1999/11/12 22:53:32  michael
+  + Added append() insert() tested append. Datetime as string works now
+
+  Revision 1.3  1999/11/11 17:31:09  michael
+  + Added Checks for all simple field types.
+  + Initial implementation of Insert/Append
+
+  Revision 1.2  1999/10/24 17:07:54  michael
+  + Added copyright header
+
+}