collect.inc 8.4 KB

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