You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

245 lines
7.7 KiB

  1. unit uutlLocalization;
  2. { Package: Utils
  3. Prefix: utl - UTiLs
  4. Beschreibung: diese Unit stellt Mechanismen zur Übersetzung von Texten mit Hilfe von PO/MO-Files zur Verfügung }
  5. {$mode objfpc}{$H+}
  6. interface
  7. uses
  8. Classes, SysUtils, gettext,
  9. uutlCommon, uutlGenerics, uutlStreamHelper;
  10. type
  11. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  12. TutlLocalizationItem = class(TObject)
  13. Name, Comment: String;
  14. constructor Create;
  15. end;
  16. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  17. TutlLocalizationDatabase = class(TObject)
  18. private type
  19. TStringObjMap = specialize TutlMap<String, TutlLocalizationItem>;
  20. private
  21. fStringList: TStringObjMap;
  22. fLangFile: TMOFile;
  23. function GetCount: Integer;
  24. function GetObject(Index: Integer): TutlLocalizationItem;
  25. public
  26. property Count : Integer read GetCount;
  27. property Objects[Index: Integer]: TutlLocalizationItem read GetObject;
  28. function AddName(const Name, Comment: string): TutlLocalizationItem;
  29. function RemoveName(const Name: string): boolean;
  30. procedure LoadFromStream(const aStream: TStream);
  31. procedure SaveToStream(const aStream: TStream);
  32. procedure LoadLanguage(const aStream: TStream);
  33. function Translate(const Name: string): string;
  34. constructor Create;
  35. destructor Destroy; override;
  36. end;
  37. function utlLocalizationDatabase: TutlLocalizationDatabase;
  38. function __(Name: string; Default: string = #0): string; overload;
  39. implementation
  40. uses
  41. Dialogs, uvfsManager;
  42. var
  43. Entity: TutlLocalizationDatabase;
  44. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  45. function utlLocalizationDatabase: TutlLocalizationDatabase;
  46. var
  47. str: IStreamHandle;
  48. begin
  49. if not Assigned(Entity) then begin
  50. Entity := TutlLocalizationDatabase.Create;
  51. if vfsManager.ReadFile('lang/strings', str) then
  52. Entity.LoadFromStream(str.GetStream);
  53. end;
  54. result := Entity;
  55. end;
  56. function __(Name: string; Default: string): string;
  57. begin
  58. if Default=#0 then
  59. Default := Name;
  60. Result := utlLocalizationDatabase.Translate(Name);
  61. if (Result = '') then
  62. Result := Default;
  63. end;
  64. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  65. //TutlLocalizationItem////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  66. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  67. //erstellt das Objekt
  68. constructor TutlLocalizationItem.Create;
  69. begin
  70. inherited Create;
  71. Name := '';
  72. Comment := '';
  73. end;
  74. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  75. //TutlLocalizationDatabase///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  76. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  77. //Get-Methode der Count-Eigenschaft
  78. function TutlLocalizationDatabase.GetCount: Integer;
  79. begin
  80. result := fStringList.Count;
  81. end;
  82. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  83. //Get-Methode der Value-Eigenschaft
  84. function TutlLocalizationDatabase.GetObject(Index: Integer): TutlLocalizationItem;
  85. begin
  86. if (Index >= 0) and (Index < fStringList.Count) then
  87. result := fStringList.ValueAt[Index]
  88. else
  89. result := nil;
  90. end;
  91. function TutlLocalizationDatabase.AddName(const Name, Comment: string): TutlLocalizationItem;
  92. var
  93. e: TutlLocalizationItem;
  94. i: Integer;
  95. begin
  96. i := fStringList.IndexOf(Name);
  97. if i >= 0 then
  98. Result:= Objects[i]
  99. else begin
  100. e := TutlLocalizationItem.Create;
  101. e.Name := Name;
  102. e.Comment := Comment;
  103. fStringList.Add(e.Name, e);
  104. result := e;
  105. end;
  106. end;
  107. function TutlLocalizationDatabase.RemoveName(const Name: string): boolean;
  108. begin
  109. Result:= fStringList.IndexOf(Name) >= 0;
  110. if Result then
  111. fStringList.Delete(Name);
  112. end;
  113. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  114. //läd die Datenbank aus einem Stream
  115. //@aStream: Stream aus der geladen werden soll;
  116. procedure TutlLocalizationDatabase.LoadFromStream(const aStream: TStream);
  117. const
  118. HEADER = 'StringDatabase';
  119. var
  120. rd: TutlStreamReader;
  121. csv: TutlCSVList;
  122. co: string;
  123. begin
  124. rd:= TutlStreamReader.Create(aStream);
  125. try
  126. if HEADER <> rd.ReadLine then
  127. raise Exception.Create('TStringDatabase.LoadFromStream - invalid Stream');
  128. fStringList.Clear;
  129. csv:= TutlCSVList.Create;
  130. try
  131. csv.Delimiter:= ';';
  132. csv.StrictDelimitedText:= rd.ReadLine;
  133. while csv.Count>=1 do begin
  134. co:= '';
  135. if csv.Count>1 then
  136. co:= csv[1];
  137. AddName(csv[0],co);
  138. // next line
  139. csv.StrictDelimitedText:= rd.ReadLine;
  140. end;
  141. finally
  142. FreeAndNil(csv);
  143. end;
  144. finally
  145. FreeAndNil(rd);
  146. end;
  147. end;
  148. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  149. //speichert die Datenbank in einem Stream
  150. //@aStream: Stream in dem gespeichert werden soll;
  151. procedure TutlLocalizationDatabase.SaveToStream(const aStream: TStream);
  152. const
  153. HEADER = 'StringDatabase';
  154. var
  155. i: Integer;
  156. wr: TutlStreamWriter;
  157. csv: TutlCSVList;
  158. o: TutlLocalizationItem;
  159. begin
  160. wr:= TutlStreamWriter.Create(aStream);
  161. try
  162. wr.WriteLine(HEADER);
  163. csv:= TutlCSVList.Create;
  164. try
  165. csv.Delimiter:= ';';
  166. for i := 0 to fStringList.Count-1 do begin
  167. csv.Clear;
  168. o:= Objects[i];
  169. csv.Add(o.Name);
  170. csv.Add(o.Comment);
  171. wr.WriteLine(csv.StrictDelimitedText);
  172. end;
  173. finally
  174. FreeAndNil(csv);
  175. end;
  176. finally
  177. FreeAndNil(wr);
  178. end;
  179. end;
  180. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  181. procedure TutlLocalizationDatabase.LoadLanguage(const aStream: TStream);
  182. begin
  183. fLangFile.Free;
  184. fLangFile := nil;
  185. fLangFile := TMOFile.Create(aStream);
  186. end;
  187. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  188. function TutlLocalizationDatabase.Translate(const Name: string): string;
  189. begin
  190. if Assigned(fLangFile) then
  191. Result := UTF8Encode(fLangFile.Translate(Name))
  192. else
  193. Result := '';
  194. end;
  195. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  196. //erstellt das Objekt
  197. constructor TutlLocalizationDatabase.Create;
  198. begin
  199. inherited Create;
  200. fStringList := TStringObjMap.Create(True);
  201. fLangFile := nil;
  202. end;
  203. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  204. //gibt das Objekt frei
  205. destructor TutlLocalizationDatabase.Destroy;
  206. begin
  207. fLangFile.Free;
  208. fStringList.Free;
  209. inherited Destroy;
  210. end;
  211. finalization
  212. FreeAndNil(Entity);
  213. end.