datasource.inc 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550
  1. { ---------------------------------------------------------------------
  2. TDatalink
  3. ---------------------------------------------------------------------}
  4. Constructor TDataLink.Create;
  5. begin
  6. Inherited Create;
  7. FBufferCount:=1;
  8. FDatasourceFixed:=False;
  9. end;
  10. Destructor TDataLink.Destroy;
  11. begin
  12. Factive:=False;
  13. FEditing:=False;
  14. FDataSourceFixed:=False;
  15. DataSource:=Nil;
  16. Inherited Destroy;
  17. end;
  18. Procedure TDataLink.ActiveChanged;
  19. begin
  20. end;
  21. Procedure TDataLink.CheckActiveAndEditing;
  22. Var
  23. B : Boolean;
  24. begin
  25. B:=Assigned(DataSource) and (DataSource.State<>dsInactive);
  26. If B<>FActive then
  27. begin
  28. FActive:=B;
  29. ActiveChanged;
  30. end;
  31. B:=Assigned(DataSource) and (DataSource.State in dsEditModes) and Not FReadOnly;
  32. If B<>FEditing Then
  33. begin
  34. FEditing:=B;
  35. EditingChanged;
  36. end;
  37. end;
  38. Procedure TDataLink.CheckBrowseMode;
  39. begin
  40. end;
  41. Function TDataLink.CalcFirstRecord(Index : Integer) : Integer;
  42. { recalculates index of first record in buffer,
  43. and returns number of record scrolled.}
  44. Var
  45. A, // Index of active record in buffer
  46. F, // Index of current first record in buffer
  47. L : Integer; // index of Last (for us) record in buffer;
  48. begin
  49. Result:=0;
  50. A:=DataSource.DataSet.FActiveRecord;
  51. F:=FFirstRecord+Index;
  52. L:=F+FBufferCount-1;
  53. If A>L Then
  54. Result:=A-L
  55. else If A<F Then
  56. Result:=A-F;
  57. FFirstRecord:=F+Result;
  58. {$IfDef dsDebug}
  59. WriteLn('CalcFirstRecord: FFirstRecord=',FFirstRecord,' Scrolled=',Result);
  60. {$Endif}
  61. end;
  62. Procedure TDataLink.CalcRange;
  63. var
  64. aMax, aMin: integer;
  65. begin
  66. aMin:= DataSet.FActiveRecord - FBufferCount + 1;
  67. If aMin < 0 Then aMin:= 0;
  68. aMax:= Dataset.FBufferCount - FBufferCount;
  69. If aMax < 0 then aMax:= 0;
  70. If aMax>DataSet.FActiveRecord Then aMax:=DataSet.FActiveRecord;
  71. If FFirstRecord < aMin Then FFirstRecord:= aMin;
  72. If FFirstrecord > aMax Then FFirstRecord:= aMax;
  73. If (FfirstRecord<>0) And
  74. (DataSet.FActiveRecord - FFirstRecord < FBufferCount -1) Then
  75. Dec(FFirstRecord, 1);
  76. end;
  77. Procedure TDataLink.DataEvent(Event: TDataEvent; Info: Longint);
  78. begin
  79. Case Event of
  80. deFieldChange,
  81. deRecordChange :
  82. If Not FUpdatingRecord then
  83. RecordChanged(TField(Info));
  84. deDataSetChange:
  85. begin
  86. SetActive(DataSource.DataSet.Active);
  87. CalcFirstRecord(Info);
  88. DatasetChanged;
  89. end;
  90. deDataSetScroll:
  91. DatasetScrolled(CalcFirstRecord(Info));
  92. deLayoutChange:
  93. begin
  94. CalcFirstRecord(Info);
  95. LayoutChanged;
  96. end;
  97. deUpdateRecord:
  98. UpdateRecord;
  99. deUpdateState:
  100. CheckActiveAndEditing;
  101. deCheckBrowseMode:
  102. CheckBrowseMode;
  103. deFocusControl:
  104. FocusControl(TFieldRef(Info));
  105. end;
  106. end;
  107. Procedure TDataLink.DataSetChanged;
  108. begin
  109. RecordChanged(Nil);
  110. end;
  111. Procedure TDataLink.DataSetScrolled(Distance: Integer);
  112. begin
  113. DataSetChanged;
  114. end;
  115. Procedure TDataLink.EditingChanged;
  116. begin
  117. end;
  118. Procedure TDataLink.FocusControl(Field: TFieldRef);
  119. begin
  120. end;
  121. Function TDataLink.GetActiveRecord: Integer;
  122. begin
  123. Result:=Dataset.FActiveRecord - FFirstRecord;
  124. end;
  125. Function TDatalink.GetDataSet : TDataset;
  126. begin
  127. Result:=FDataSource.DataSet
  128. end;
  129. Function TDataLink.GetBOF: Boolean;
  130. begin
  131. Result:=DataSet.BOF
  132. end;
  133. Function TDataLink.GetBufferCount: Integer;
  134. begin
  135. Result:=FBufferCount;
  136. end;
  137. Function TDataLink.GetEOF: Boolean;
  138. begin
  139. Result:=DataSet.EOF
  140. end;
  141. Function TDataLink.GetRecordCount: Integer;
  142. Var D : TDataSet;
  143. begin
  144. Result:=Dataset.FRecordCount;
  145. If Result>BufferCount then
  146. Result:=BufferCount;
  147. end;
  148. Procedure TDataLink.LayoutChanged;
  149. begin
  150. DataSetChanged;
  151. end;
  152. Function TDataLink.MoveBy(Distance: Integer): Integer;
  153. begin
  154. Result:=DataSet.MoveBy(Distance);
  155. end;
  156. Procedure TDataLink.RecordChanged(Field: TField);
  157. begin
  158. end;
  159. Procedure TDataLink.SetActiveRecord(Value: Integer);
  160. begin
  161. Dataset.FActiveRecord:=Value + FFirstRecord;
  162. end;
  163. Procedure TDataLink.SetBufferCount(Value: Integer);
  164. begin
  165. If FBufferCount<>Value then
  166. begin
  167. FBufferCount:=Value;
  168. if Active then begin
  169. DataSet.RecalcBufListSize;
  170. CalcRange;
  171. end;
  172. end;
  173. end;
  174. procedure TDataLink.SetActive(AActive: Boolean);
  175. begin
  176. if Active <> AActive then
  177. begin
  178. FActive := AActive;
  179. // !!!: Set internal state
  180. ActiveChanged;
  181. end;
  182. end;
  183. Procedure TDataLink.SetDataSource(Value : TDatasource);
  184. begin
  185. if not FDataSourceFixed then
  186. begin
  187. if Assigned(DataSource) then
  188. Begin
  189. DataSource.UnregisterDatalink(Self);
  190. FDataSource := nil;
  191. CheckActiveAndEditing;
  192. End;
  193. FDataSource := Value;
  194. if Assigned(DataSource) then
  195. begin
  196. DataSource.RegisterDatalink(Self);
  197. CheckActiveAndEditing;
  198. End;
  199. end;
  200. end;
  201. Procedure TDatalink.SetReadOnly(Value : Boolean);
  202. begin
  203. If FReadOnly<>Value then
  204. begin
  205. FReadOnly:=Value;
  206. CheckActiveAndEditing;
  207. end;
  208. end;
  209. Procedure TDataLink.UpdateData;
  210. begin
  211. end;
  212. Function TDataLink.Edit: Boolean;
  213. begin
  214. If Not FReadOnly then
  215. DataSource.Edit;
  216. // Triggered event will set FEditing
  217. Result:=FEditing;
  218. end;
  219. Procedure TDataLink.UpdateRecord;
  220. begin
  221. FUpdatingRecord:=True;
  222. Try
  223. UpdateData;
  224. finally
  225. FUpdatingRecord:=False;
  226. end;
  227. end;
  228. { ---------------------------------------------------------------------
  229. TDetailDataLink
  230. ---------------------------------------------------------------------}
  231. Function TDetailDataLink.GetDetailDataSet: TDataSet;
  232. begin
  233. end;
  234. { ---------------------------------------------------------------------
  235. TMasterDataLink
  236. ---------------------------------------------------------------------}
  237. constructor TMasterDataLink.Create(ADataSet: TDataSet);
  238. begin
  239. end;
  240. destructor TMasterDataLink.Destroy;
  241. begin
  242. inherited Destroy;
  243. end;
  244. Procedure TMasterDataLink.ActiveChanged;
  245. begin
  246. end;
  247. Procedure TMasterDataLink.CheckBrowseMode;
  248. begin
  249. end;
  250. Function TMasterDataLink.GetDetailDataSet: TDataSet;
  251. begin
  252. end;
  253. Procedure TMasterDataLink.LayoutChanged;
  254. begin
  255. end;
  256. Procedure TMasterDataLink.RecordChanged(Field: TField);
  257. begin
  258. end;
  259. procedure TMasterDatalink.SetFieldNames(const Value: string);
  260. begin
  261. end;
  262. { ---------------------------------------------------------------------
  263. TDatasource
  264. ---------------------------------------------------------------------}
  265. Constructor TDataSource.Create(AOwner: TComponent);
  266. begin
  267. Inherited Create(AOwner);
  268. FDatalinks:=TList.Create;
  269. FEnabled:=True;
  270. FAutoEdit:=True;
  271. end;
  272. Destructor TDataSource.Destroy;
  273. begin
  274. FOnStateCHange:=Nil;
  275. Dataset:=Nil;
  276. With FDataLinks do
  277. While Count>0 do
  278. TDatalink(Items[Count - 1]).DataSource:=Nil;
  279. FDatalinks.Free;
  280. inherited Destroy;
  281. end;
  282. Procedure TDatasource.Edit;
  283. begin
  284. If (State=dsBrowse) and AutoEdit Then
  285. Dataset.Edit;
  286. end;
  287. Function TDataSource.IsLinkedTo(ADataSet: TDataSet): Boolean;
  288. begin
  289. Result:=False;
  290. end;
  291. procedure TDatasource.DistributeEvent(Event: TDataEvent; Info: Longint);
  292. Var
  293. i : Longint;
  294. begin
  295. With FDatalinks do
  296. begin
  297. For I:=0 to Count-1 do
  298. With TDatalink(Items[i]) do
  299. If Not VisualControl Then
  300. DataEvent(Event,Info);
  301. For I:=0 to Count-1 do
  302. With TDatalink(Items[i]) do
  303. If VisualControl Then
  304. DataEvent(Event,Info);
  305. end;
  306. end;
  307. procedure TDatasource.RegisterDataLink(DataLink: TDataLink);
  308. begin
  309. FDatalinks.Add(DataLink);
  310. if Assigned(DataSet) then
  311. DataSet.RecalcBufListSize;
  312. end;
  313. procedure TDatasource.SetDataSet(ADataSet: TDataSet);
  314. begin
  315. If FDataset<>Nil Then
  316. Begin
  317. FDataset.UnRegisterDataSource(Self);
  318. FDataSet:=nil;
  319. ProcessEvent(deUpdateState,0);
  320. End;
  321. If ADataset<>Nil Then
  322. begin
  323. ADataset.RegisterDatasource(Self);
  324. FDataSet:=ADataset;
  325. ProcessEvent(deUpdateState,0);
  326. End;
  327. end;
  328. procedure TDatasource.SetEnabled(Value: Boolean);
  329. begin
  330. FEnabled:=Value;
  331. end;
  332. Procedure TDatasource.DoDataChange (Info : Pointer);
  333. begin
  334. If Assigned(OnDataChange) Then
  335. OnDataChange(Self,TField(Info));
  336. end;
  337. Procedure TDatasource.DoStateChange;
  338. begin
  339. If Assigned(OnStateChange) Then
  340. OnStateChange(Self);
  341. end;
  342. Procedure TDatasource.DoUpdateData;
  343. begin
  344. If Assigned(OnUpdateData) Then
  345. OnUpdateData(Self);
  346. end;
  347. procedure TDatasource.UnregisterDataLink(DataLink: TDataLink);
  348. begin
  349. FDatalinks.Remove(Datalink);
  350. If Dataset<>Nil then
  351. DataSet.RecalcBufListSize;
  352. //Dataset.SetBufListSize(DataLink.BufferCount);
  353. end;
  354. procedure TDataSource.ProcessEvent(Event : TDataEvent; Info : longint);
  355. Const
  356. OnDataChangeEvents = [deRecordChange, deDataSetChange,
  357. deDataSetScroll,
  358. deLayoutChange,deUpdateState];
  359. Var
  360. NeedDataChange : Boolean;
  361. FLastState : TdataSetState;
  362. begin
  363. // Special UpdateState handling.
  364. If Event=deUpdateState then
  365. begin
  366. NeedDataChange:=(FState=dsInactive);
  367. FLastState:=FState;
  368. If Assigned(Dataset) then
  369. FState:=Dataset.State
  370. else
  371. FState:=dsInactive;
  372. // Don't do events if nothing changed.
  373. If FState=FlastState then
  374. exit;
  375. end
  376. else
  377. NeedDataChange:=True;
  378. DistributeEvent(Event,Info);
  379. // Extra handlers
  380. If Not (csDestroying in ComponentState) then
  381. begin
  382. If (Event=deUpdateState) then
  383. DoStateChange;
  384. If (Event in OnDataChangeEvents) and
  385. NeedDataChange Then
  386. DoDataChange(Nil);
  387. If (Event = deFieldChange) Then
  388. DoDataCHange(Pointer(Info));
  389. If (Event=deUpdateRecord) then
  390. DoUpdateData;
  391. end;
  392. end;