datasource.inc 8.9 KB

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