inicol.pp 8.4 KB

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