collect.inc 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477
  1. {%MainUnit classes.pp}
  2. {
  3. This file is part of the Free Component Library (FCL)
  4. Copyright (c) 1999-2000 by the Free Pascal development team
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. {****************************************************************************}
  12. {* TCollectionItem *}
  13. {****************************************************************************}
  14. function TCollectionItem.GetIndex: Integer;
  15. begin
  16. if FCollection<>nil then
  17. Result:=FCollection.FItems.IndexOf(Pointer(Self))
  18. else
  19. Result:=-1;
  20. end;
  21. procedure TCollectionItem.SetCollection(Value: TCollection);
  22. begin
  23. IF Value<>FCollection then
  24. begin
  25. If FCollection<>Nil then FCollection.RemoveItem(Self);
  26. if Value<>Nil then Value.InsertItem(Self);
  27. end;
  28. end;
  29. procedure TCollectionItem.Changed(AllItems: Boolean);
  30. begin
  31. If (FCollection<>Nil) and (FCollection.UpdateCount=0) then
  32. begin
  33. If AllItems then
  34. FCollection.Update(Nil)
  35. else
  36. FCollection.Update(Self);
  37. end;
  38. end;
  39. function TCollectionItem.GetNamePath: string;
  40. begin
  41. If FCollection<>Nil then
  42. Result:=FCollection.GetNamePath+'['+IntToStr(Index)+']'
  43. else
  44. Result:=ClassName;
  45. end;
  46. function TCollectionItem.GetOwner: TPersistent;
  47. begin
  48. Result:=FCollection;
  49. end;
  50. function TCollectionItem.GetDisplayName: string;
  51. begin
  52. Result:=ClassName;
  53. end;
  54. procedure TCollectionItem.SetIndex(Value: Integer);
  55. Var Temp : Longint;
  56. begin
  57. Temp:=GetIndex;
  58. If (Temp>-1) and (Temp<>Value) then
  59. begin
  60. FCollection.FItems.Move(Temp,Value);
  61. Changed(True);
  62. end;
  63. end;
  64. procedure TCollectionItem.SetDisplayName(const Value: string);
  65. begin
  66. Changed(False);
  67. end;
  68. constructor TCollectionItem.Create(ACollection: TCollection);
  69. begin
  70. Inherited Create;
  71. SetCollection(ACollection);
  72. end;
  73. destructor TCollectionItem.Destroy;
  74. begin
  75. SetCollection(Nil);
  76. Inherited Destroy;
  77. end;
  78. {****************************************************************************}
  79. {* TCollectionEnumerator *}
  80. {****************************************************************************}
  81. constructor TCollectionEnumerator.Create(ACollection: TCollection);
  82. begin
  83. inherited Create;
  84. FCollection := ACollection;
  85. FPosition := -1;
  86. end;
  87. function TCollectionEnumerator.GetCurrent: TCollectionItem;
  88. begin
  89. Result := FCollection.Items[FPosition];
  90. end;
  91. function TCollectionEnumerator.MoveNext: Boolean;
  92. begin
  93. Inc(FPosition);
  94. Result := FPosition < FCollection.Count;
  95. end;
  96. {****************************************************************************}
  97. {* TCollection *}
  98. {****************************************************************************}
  99. function TCollection.Owner: TPersistent;
  100. begin
  101. result:=getowner;
  102. end;
  103. function TCollection.GetCount: Integer;
  104. begin
  105. Result:=FItems.Count;
  106. end;
  107. Procedure TCollection.SetPropName;
  108. Var
  109. TheOwner : TPersistent;
  110. PropList : PPropList;
  111. I, PropCount : Integer;
  112. begin
  113. FPropName:='';
  114. TheOwner:=GetOwner;
  115. if (TheOwner=Nil) Or (TheOwner.Classinfo=Nil) Then Exit;
  116. // get information from the owner RTTI
  117. PropCount:=GetPropList(TheOwner, PropList);
  118. Try
  119. For I:=0 To PropCount-1 Do
  120. If (PropList^[i]^.PropType^.Kind=tkClass) And
  121. (GetObjectProp(TheOwner, PropList^[i], ClassType)=Self) Then
  122. Begin
  123. FPropName:=PropList^[i]^.Name;
  124. Exit;
  125. End;
  126. Finally
  127. FreeMem(PropList);
  128. End;
  129. end;
  130. function TCollection.GetPropName: string;
  131. Var
  132. TheOwner : TPersistent;
  133. begin
  134. Result:=FPropNAme;
  135. TheOwner:=GetOwner;
  136. If (Result<>'') or (TheOwner=Nil) Or (TheOwner.Classinfo=Nil) then exit;
  137. SetPropName;
  138. Result:=FPropName;
  139. end;
  140. procedure TCollection.InsertItem(Item: TCollectionItem);
  141. begin
  142. If Not(Item Is FitemClass) then
  143. exit;
  144. FItems.add(Pointer(Item));
  145. Item.FCollection:=Self;
  146. Item.FID:=FNextID;
  147. inc(FNextID);
  148. SetItemName(Item);
  149. Notify(Item,cnAdded);
  150. Changed;
  151. end;
  152. procedure TCollection.RemoveItem(Item: TCollectionItem);
  153. Var
  154. I : Integer;
  155. begin
  156. Notify(Item,cnExtracting);
  157. I:=FItems.IndexOfItem(Item,fromEnd);
  158. If (I<>-1) then
  159. FItems.Delete(I);
  160. Item.FCollection:=Nil;
  161. Changed;
  162. end;
  163. function TCollection.GetAttrCount: Integer;
  164. begin
  165. Result:=0;
  166. end;
  167. function TCollection.GetAttr(Index: Integer): string;
  168. begin
  169. Result:='';
  170. end;
  171. function TCollection.GetItemAttr(Index, ItemIndex: Integer): string;
  172. begin
  173. Result:=TCollectionItem(FItems.Items[ItemIndex]).DisplayName;
  174. end;
  175. function TCollection.GetEnumerator: TCollectionEnumerator;
  176. begin
  177. Result := TCollectionEnumerator.Create(Self);
  178. end;
  179. function TCollection.GetNamePath: string;
  180. var o : TPersistent;
  181. begin
  182. o:=getowner;
  183. if assigned(o) and (propname<>'') then
  184. result:=o.getnamepath+'.'+propname
  185. else
  186. result:=classname;
  187. end;
  188. procedure TCollection.Changed;
  189. begin
  190. if FUpdateCount=0 then
  191. Update(Nil);
  192. end;
  193. function TCollection.GetItem(Index: Integer): TCollectionItem;
  194. begin
  195. Result:=TCollectionItem(FItems.Items[Index]);
  196. end;
  197. procedure TCollection.SetItem(Index: Integer; Value: TCollectionItem);
  198. begin
  199. TCollectionItem(FItems.items[Index]).Assign(Value);
  200. end;
  201. procedure TCollection.SetItemName(Item: TCollectionItem);
  202. begin
  203. end;
  204. procedure TCollection.Update(Item: TCollectionItem);
  205. begin
  206. FPONotifyObservers(Self,ooChange,Pointer(Item));
  207. end;
  208. constructor TCollection.Create(AItemClass: TCollectionItemClass);
  209. begin
  210. inherited create;
  211. FItemClass:=AItemClass;
  212. FItems:=TFpList.Create;
  213. end;
  214. destructor TCollection.Destroy;
  215. begin
  216. FUpdateCount:=1; // Prevent OnChange
  217. try
  218. if Assigned(FItems) then
  219. DoClear;
  220. Finally
  221. FUpdateCount:=0;
  222. end;
  223. FItems.Free;
  224. Inherited Destroy;
  225. end;
  226. function TCollection.Add: TCollectionItem;
  227. begin
  228. Result:=FItemClass.Create(Self);
  229. end;
  230. procedure TCollection.Assign(Source: TPersistent);
  231. Var I : Longint;
  232. begin
  233. If Source is TCollection then
  234. begin
  235. BeginUpdate;
  236. try
  237. Clear;
  238. For I:=0 To TCollection(Source).Count-1 do
  239. Add.Assign(TCollection(Source).Items[I]);
  240. finally
  241. EndUpdate;
  242. end;
  243. exit;
  244. end
  245. else
  246. Inherited Assign(Source);
  247. end;
  248. procedure TCollection.BeginUpdate;
  249. begin
  250. inc(FUpdateCount);
  251. end;
  252. procedure TCollection.Clear;
  253. begin
  254. if FItems.Count=0 then
  255. exit; // Prevent Changed
  256. BeginUpdate;
  257. try
  258. DoClear;
  259. finally
  260. EndUpdate;
  261. end;
  262. end;
  263. procedure TCollection.DoClear;
  264. begin
  265. While FItems.Count>0 do TCollectionItem(FItems.Last).Free;
  266. end;
  267. procedure TCollection.EndUpdate;
  268. begin
  269. if FUpdateCount>0 then
  270. dec(FUpdateCount);
  271. if FUpdateCount=0 then
  272. Changed;
  273. end;
  274. function TCollection.FindItemID(ID: Integer): TCollectionItem;
  275. Var
  276. I : Longint;
  277. begin
  278. For I:=0 to Fitems.Count-1 do
  279. begin
  280. Result:=TCollectionItem(FItems.items[I]);
  281. If Result.Id=Id then
  282. exit;
  283. end;
  284. Result:=Nil;
  285. end;
  286. procedure TCollection.Delete(Index: Integer);
  287. Var
  288. Item : TCollectionItem;
  289. begin
  290. Item:=TCollectionItem(FItems[Index]);
  291. Notify(Item,cnDeleting);
  292. Item.Free;
  293. end;
  294. function TCollection.Insert(Index: Integer): TCollectionItem;
  295. begin
  296. Result:=Add;
  297. Result.Index:=Index;
  298. end;
  299. procedure TCollection.Notify(Item: TCollectionItem;Action: TCollectionNotification);
  300. begin
  301. if Assigned(FObservers) and (FUpdateCount = 0) then
  302. Case Action of
  303. cnAdded : FPONotifyObservers(Self,ooAddItem,Pointer(Item));
  304. cnExtracting : FPONotifyObservers(Self,ooDeleteItem,Pointer(Item));
  305. cnDeleting : FPONotifyObservers(Self,ooDeleteItem,Pointer(Item));
  306. end;
  307. end;
  308. procedure TCollection.Sort(Const Compare : TCollectionSortCompare_Context; Context : Pointer);
  309. begin
  310. BeginUpdate;
  311. try
  312. FItems.Sort(TListSortComparer_Context(Compare),Context);
  313. Finally
  314. EndUpdate;
  315. end;
  316. end;
  317. procedure TCollection.Sort(Const Compare : TCollectionSortCompare);
  318. begin
  319. BeginUpdate;
  320. try
  321. FItems.Sort(TListSortCompare(Compare));
  322. Finally
  323. EndUpdate;
  324. end;
  325. end;
  326. procedure TCollection.Exchange(Const Index1, index2: integer);
  327. begin
  328. FItems.Exchange(Index1,Index2);
  329. if FUpdateCount = 0 then
  330. FPONotifyObservers(Self,ooChange,Nil);
  331. end;
  332. procedure TCollection.Move(const Index1, index2: integer);
  333. begin
  334. Items[Index1].Index:=Index2;
  335. end;
  336. {****************************************************************************}
  337. {* TOwnedCollection *}
  338. {****************************************************************************}
  339. Constructor TOwnedCollection.Create(AOwner: TPersistent; AItemClass: TCollectionItemClass);
  340. Begin
  341. FOwner := AOwner;
  342. inherited Create(AItemClass);
  343. end;
  344. Function TOwnedCollection.GetOwner: TPersistent;
  345. begin
  346. Result:=FOwner;
  347. end;