inicol.pp 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  1. {
  2. This file is part of the Free Component Library (FCL)
  3. Copyright (c) 1999-2000 by Michael Van Canneyt and Florian Klaempfl
  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. {$mode objfpc}
  11. {$h+}
  12. unit inicol;
  13. interface
  14. Uses SysUtils,Classes,Inifiles;
  15. Type
  16. { TIniCollectionItem }
  17. TIniCollectionItem = Class(TCollectionItem)
  18. protected
  19. function GetSectionName: String; virtual; abstract;
  20. procedure SetSectionName(const Value: String); virtual; abstract;
  21. Public
  22. Procedure SaveToIni(Ini: TCustomInifile; Section : String); Virtual; Abstract;
  23. Procedure LoadFromIni(Ini: TCustomInifile; Section : String); Virtual; Abstract;
  24. Procedure SaveToFile(FileName : String; Section : String);
  25. Procedure LoadFromFile(FileName : String; Section : String);
  26. Property SectionName : String Read GetSectionName Write SetSectionName;
  27. end;
  28. TIniCollection = Class(TCollection)
  29. private
  30. FFileName: String;
  31. FGlobalSection: String;
  32. protected
  33. FPrefix: String; // Descendent must set this.
  34. FSectionPrefix : String; // Descendent must set this too.
  35. Public
  36. Procedure Load;
  37. Procedure Save;
  38. Procedure SaveToIni(Ini: TCustomInifile; Section : String); virtual;
  39. Procedure SaveToFile(AFileName : String; Section : String);
  40. Procedure LoadFromIni(Ini: TCustomInifile; Section : String); virtual;
  41. Procedure LoadFromFile(AFileName : String; Section : String);
  42. Property Prefix : String Read FPrefix;
  43. Property SectionPrefix : String Read FSectionPrefix;
  44. Property FileName : String Read FFileName Write FFileName;
  45. Property GlobalSection : String Read FGlobalSection Write FGlobalSection;
  46. end;
  47. { TNamedIniCollectionItem }
  48. TNamedIniCollectionItem = Class(TIniCollectionItem)
  49. private
  50. procedure SetName(const AValue: String);
  51. Protected
  52. FName : String;
  53. FUserData : TObject;
  54. Protected
  55. Procedure SetCollection(Value : TCollection); override;
  56. function GetSectionName: String; override;
  57. procedure SetSectionName(const Value: String); override;
  58. Public
  59. Property UserData : TObject Read FUserData Write FUserData;
  60. Published
  61. Property Name : String Read FName Write SetName;
  62. end;
  63. { TNamedIniCollection }
  64. TNamedIniCollection = Class(TIniCollection)
  65. private
  66. function GetNamedItem(Index: Integer): TNamedIniCollectionItem;
  67. procedure SetNamedItem(Index: Integer; const AValue: TNamedIniCollectionItem);
  68. Public
  69. Function IndexOfUserData(UserData : TObject) : Integer;
  70. Function IndexOfName(Const AName : String) : Integer;
  71. Function FindByName(Const AName : string) : TNamedIniCollectionItem;
  72. Function FindByUserData(UserData : TObject) : TNamedIniCollectionItem;
  73. Property NamedItems [Index: Integer] : TNamedIniCollectionItem Read GetNamedItem Write SetNamedItem; default;
  74. end;
  75. EIniCol = Class(Exception);
  76. Const
  77. KeyCount = 'Count';
  78. SGlobal = 'Global';
  79. implementation
  80. { TIniCollectionItem }
  81. resourcestring
  82. SErrNoFileName = '%s: No filename specified.';
  83. SErrNoSection = '%s: No [global] section specified.';
  84. SErrDuplicateName = 'Duplicate names "%s" not allowed in collection';
  85. procedure TIniCollectionItem.LoadFromFile(FileName, Section: String);
  86. Var
  87. Ini : TMemInifile;
  88. begin
  89. Ini:=TMemInifile.Create(FileName);
  90. Try
  91. LoadFromIni(Ini,Section);
  92. Finally
  93. Ini.Free;
  94. end;
  95. end;
  96. procedure TIniCollectionItem.SaveToFile(FileName, Section: String);
  97. Var
  98. Ini : TMemInifile;
  99. begin
  100. Ini:=TMemInifile.Create(FileName);
  101. Try
  102. SaveToIni(Ini,Section);
  103. Ini.UpdateFile;
  104. Finally
  105. Ini.Free;
  106. end;
  107. end;
  108. { TIniCollection }
  109. procedure TIniCollection.Load;
  110. begin
  111. If (FFileName='') then
  112. Raise EIniCol.CreateFmt(SErrNoFileName,[ClassName]);
  113. If (GlobalSection='') then
  114. Raise EIniCol.CreateFmt(SErrNoSection,[ClassName]);
  115. LoadFromFile(FFileName,GlobalSection)
  116. end;
  117. procedure TIniCollection.LoadFromFile(AFileName, Section: String);
  118. Var
  119. Ini : TMemIniFile;
  120. begin
  121. Ini:=TMemInifile.Create(AFileName);
  122. Try
  123. LoadFromIni(Ini,Section);
  124. FFileName:=AFileName;
  125. FGlobalSection:=Section;
  126. Finally
  127. ini.Free;
  128. end;
  129. end;
  130. procedure TIniCollection.LoadFromIni(Ini: TCustomInifile; Section: String);
  131. Var
  132. ACount,I : Integer;
  133. N,SP : String;
  134. begin
  135. Clear;
  136. SP:=FSectionPrefix;
  137. If (SP<>'') then
  138. SP:=SP+'_';
  139. ACount:=Ini.ReadInteger(Section,KeyCount,0);
  140. For I:=1 to ACount do
  141. begin
  142. N:=Ini.ReadString(Section,Prefix+IntToStr(I),'');
  143. If (N<>'') then
  144. With Add as TIniCollectionItem do
  145. begin
  146. SectionName:=N;
  147. LoadFromIni(Ini,SP+N);
  148. end;
  149. end;
  150. end;
  151. procedure TIniCollection.Save;
  152. begin
  153. If (FFileName='') then
  154. Raise EIniCol.CreateFmt(SErrNoFileName,[ClassName]);
  155. If (GlobalSection='') then
  156. Raise EIniCol.CreateFmt(SErrNoSection,[ClassName]);
  157. SaveToFile(FFileName,GlobalSection)
  158. end;
  159. procedure TIniCollection.SaveToFile(AFileName, Section: String);
  160. Var
  161. Ini : TMemIniFile;
  162. begin
  163. Ini:=TMemInifile.Create(AFileName);
  164. Try
  165. Ini.CacheUpdates:=True;
  166. SaveToIni(Ini,Section);
  167. Ini.UpdateFile;
  168. finally
  169. Ini.Free;
  170. end;
  171. end;
  172. procedure TIniCollection.SaveToIni(Ini: TCustomInifile; Section: String);
  173. Var
  174. S,V,SP : String;
  175. I : Integer;
  176. CI : TIniCollectionItem;
  177. begin
  178. SP:=FSectionPrefix;
  179. if (SP<>'') then
  180. SP:=SP+'_';
  181. Ini.WriteInteger(Section,KeyCount,Count);
  182. For I:=0 to Count-1 do
  183. begin
  184. CI:=(Items[i]) as TIniCollectionItem;
  185. With CI do
  186. begin
  187. V:=SectionName;
  188. S:=Prefix+IntToStr(I+1);
  189. Ini.WriteString(Section,S,V);
  190. CI.SaveToIni(Ini,SP+V);
  191. end;
  192. end;
  193. end;
  194. { ---------------------------------------------------------------------
  195. TNamedIniCollectionItem
  196. ---------------------------------------------------------------------}
  197. procedure TNamedIniCollectionItem.SetName(const AValue: String);
  198. begin
  199. If (CompareText(AValue,FName)<>0) then
  200. begin
  201. If (AValue<>'') and (Collection<>Nil) and (Collection is TNamedIniCollection) then
  202. If TNamedIniCollection(Collection).IndexOfName(AValue)<>-1 then
  203. Raise EIniCol.CreateFmt(SErrDuplicateName,[AValue]);
  204. end;
  205. FName:=AValue;
  206. end;
  207. procedure TNamedIniCollectionItem.SetCollection(Value: TCollection);
  208. begin
  209. If (Value<>Collection) then
  210. begin
  211. If (Value<>Nil) and (Value is TNamedIniCollection) Then
  212. If TNamedIniCollection(Value).IndexOfName(Self.Name)<>-1 then
  213. Raise EIniCol.CreateFmt(SErrDuplicateName,[Self.Name]);
  214. end;
  215. inherited SetCollection(Value);
  216. end;
  217. function TNamedIniCollectionItem.GetSectionName: String;
  218. begin
  219. Result:=FName;
  220. end;
  221. procedure TNamedIniCollectionItem.SetSectionName(const Value: String);
  222. begin
  223. FName:=Value; // Skip check. Ini files have only 1 named section
  224. end;
  225. { ---------------------------------------------------------------------
  226. TNamedIniCollection
  227. ---------------------------------------------------------------------}
  228. function TNamedIniCollection.GetNamedItem(Index: Integer): TNamedIniCollectionItem;
  229. begin
  230. Result:=Items[Index] as TNamedIniCollectionItem;
  231. end;
  232. procedure TNamedIniCollection.SetNamedItem(Index: Integer; const AValue: TNamedIniCollectionItem);
  233. begin
  234. Items[Index]:=AValue;
  235. end;
  236. function TNamedIniCollection.IndexOfUserData(UserData: TObject): Integer;
  237. begin
  238. If (UserData=Nil) then
  239. Result:=-1
  240. else
  241. begin
  242. Result:=Count-1;
  243. While (Result>=0) and (GetNamedItem(Result).UserData<>UserData) do
  244. Dec(Result);
  245. end;
  246. end;
  247. function TNamedIniCollection.IndexOfName(const AName: String): Integer;
  248. begin
  249. Result:=Count-1;
  250. While (Result>=0) and (CompareText(GetNamedItem(Result).Name,AName)<>0) do
  251. Dec(Result);
  252. end;
  253. function TNamedIniCollection.FindByName(const AName : string): TNamedIniCollectionItem;
  254. Var
  255. I : Integer;
  256. begin
  257. I:=IndexOfName(AName);
  258. If (I=-1) then
  259. Result:=Nil
  260. else
  261. Result:=GetNamedItem(I);
  262. end;
  263. function TNamedIniCollection.FindByUserData(UserData: TObject): TNamedIniCollectionItem;
  264. Var
  265. I : Integer;
  266. begin
  267. I:=IndexOfUserData(UserData);
  268. If (I=-1) then
  269. Result:=Nil
  270. else
  271. Result:=GetNamedItem(I);
  272. end;
  273. end.