2
0

collect.inc 8.5 KB

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