collect.inc 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465
  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. if Assigned(FItems) then
  218. DoClear;
  219. Finally
  220. FUpdateCount:=0;
  221. end;
  222. FItems.Free;
  223. Inherited Destroy;
  224. end;
  225. function TCollection.Add: TCollectionItem;
  226. begin
  227. Result:=FItemClass.Create(Self);
  228. end;
  229. procedure TCollection.Assign(Source: TPersistent);
  230. Var I : Longint;
  231. begin
  232. If Source is TCollection then
  233. begin
  234. BeginUpdate;
  235. try
  236. Clear;
  237. For I:=0 To TCollection(Source).Count-1 do
  238. Add.Assign(TCollection(Source).Items[I]);
  239. finally
  240. EndUpdate;
  241. end;
  242. exit;
  243. end
  244. else
  245. Inherited Assign(Source);
  246. end;
  247. procedure TCollection.BeginUpdate;
  248. begin
  249. inc(FUpdateCount);
  250. end;
  251. procedure TCollection.Clear;
  252. begin
  253. if FItems.Count=0 then
  254. exit; // Prevent Changed
  255. BeginUpdate;
  256. try
  257. DoClear;
  258. finally
  259. EndUpdate;
  260. end;
  261. end;
  262. procedure TCollection.DoClear;
  263. begin
  264. While FItems.Count>0 do TCollectionItem(FItems.Last).Free;
  265. end;
  266. procedure TCollection.EndUpdate;
  267. begin
  268. if FUpdateCount>0 then
  269. dec(FUpdateCount);
  270. if FUpdateCount=0 then
  271. Changed;
  272. end;
  273. function TCollection.FindItemID(ID: Integer): TCollectionItem;
  274. Var
  275. I : Longint;
  276. begin
  277. For I:=0 to Fitems.Count-1 do
  278. begin
  279. Result:=TCollectionItem(FItems.items[I]);
  280. If Result.Id=Id then
  281. exit;
  282. end;
  283. Result:=Nil;
  284. end;
  285. procedure TCollection.Delete(Index: Integer);
  286. Var
  287. Item : TCollectionItem;
  288. begin
  289. Item:=TCollectionItem(FItems[Index]);
  290. Notify(Item,cnDeleting);
  291. Item.Free;
  292. end;
  293. function TCollection.Insert(Index: Integer): TCollectionItem;
  294. begin
  295. Result:=Add;
  296. Result.Index:=Index;
  297. end;
  298. procedure TCollection.Notify(Item: TCollectionItem;Action: TCollectionNotification);
  299. begin
  300. if Assigned(FObservers) and (FUpdateCount = 0) then
  301. Case Action of
  302. cnAdded : FPONotifyObservers(Self,ooAddItem,Pointer(Item));
  303. cnExtracting : FPONotifyObservers(Self,ooDeleteItem,Pointer(Item));
  304. cnDeleting : FPONotifyObservers(Self,ooDeleteItem,Pointer(Item));
  305. end;
  306. end;
  307. procedure TCollection.Sort(Const Compare : TCollectionSortCompare);
  308. begin
  309. BeginUpdate;
  310. try
  311. FItems.Sort(TListSortCompare(Compare));
  312. Finally
  313. EndUpdate;
  314. end;
  315. end;
  316. procedure TCollection.Exchange(Const Index1, index2: integer);
  317. begin
  318. FItems.Exchange(Index1,Index2);
  319. if FUpdateCount = 0 then
  320. FPONotifyObservers(Self,ooChange,Nil);
  321. end;
  322. procedure TCollection.Move(const Index1, index2: integer);
  323. begin
  324. Items[Index1].Index:=Index2;
  325. end;
  326. {****************************************************************************}
  327. {* TOwnedCollection *}
  328. {****************************************************************************}
  329. Constructor TOwnedCollection.Create(AOwner: TPersistent; AItemClass: TCollectionItemClass);
  330. Begin
  331. FOwner := AOwner;
  332. inherited Create(AItemClass);
  333. end;
  334. Function TOwnedCollection.GetOwner: TPersistent;
  335. begin
  336. Result:=FOwner;
  337. end;