utranslation.pas 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. // SPDX-License-Identifier: GPL-3.0-only
  2. unit UTranslation;
  3. {$mode objfpc}{$H+}
  4. interface
  5. uses
  6. {$ifdef Darwin}
  7. MacOSAll,
  8. {$endif}
  9. Classes, SysUtils, UConfig, IniFiles;
  10. {*************** Language ****************}
  11. const
  12. DesignLanguage = 'en';
  13. {$ifdef Darwin}
  14. BundleResourcesDirectory = '/Contents/Resources/';
  15. {$endif}
  16. var
  17. ActiveLanguage: string;
  18. function FallbackLanguage: string;
  19. {*************** Language files ************}
  20. function LanguagePathUTF8: string;
  21. function LazPaintLanguageFile(ALanguage: string): string;
  22. {*************** Translation ***************}
  23. procedure FillLanguageList(AConfig: TLazPaintConfig);
  24. procedure TranslateLazPaint(AConfig: TIniFile);
  25. function GetResourcePath(AResource: string): string;
  26. function DoTranslate(AId, AText: string): string;
  27. function AppendQuestionMark(AText: string): string;
  28. implementation
  29. uses Forms, LCLProc, LazUTF8, BGRAUTF8, LCLTranslator, LResources, Translations,
  30. LazPaintType, LCVectorOriginal;
  31. var
  32. FMainPoFile: TPOFile;
  33. {$ifdef Darwin}
  34. function GetDarwinResourcesPath: string;
  35. var
  36. pathRef: CFURLRef;
  37. pathCFStr: CFStringRef;
  38. pathStr: shortstring;
  39. begin
  40. pathRef := CFBundleCopyBundleURL(CFBundleGetMainBundle());
  41. pathCFStr := CFURLCopyFileSystemPath(pathRef, kCFURLPOSIXPathStyle);
  42. CFStringGetPascalString(pathCFStr, @pathStr, 255, CFStringGetSystemEncoding());
  43. CFRelease(pathRef);
  44. CFRelease(pathCFStr);
  45. Result := pathStr + BundleResourcesDirectory;
  46. end;
  47. {$endif}
  48. {$ifdef Linux}
  49. function GetLinuxResourcesPath: string;
  50. var
  51. binPath: String;
  52. begin
  53. binPath := ExtractFilePath(Application.ExeName);
  54. result := ExpandFileName(binPath+'..'+PathDelim+'share'+PathDelim+'lazpaint'+PathDelim);
  55. end;
  56. {$endif}
  57. function GetResourcePath(AResource: string): string;
  58. begin
  59. {$IFDEF WINDOWS}
  60. result:=SysToUTF8(ExtractFilePath(Application.ExeName))+AResource+PathDelim;
  61. {$ELSE}
  62. {$IFDEF DARWIN}
  63. if DirectoryExists(GetDarwinResourcesPath+AResource) then
  64. result := GetDarwinResourcesPath+AResource+PathDelim
  65. else
  66. {$ELSE}
  67. {$IFDEF LINUX}
  68. if DirectoryExists(GetLinuxResourcesPath+AResource) then
  69. result := GetLinuxResourcesPath+AResource+PathDelim
  70. else
  71. {$ENDIF}
  72. {$ENDIF}
  73. result:=ExtractFilePath(Application.ExeName)+AResource+PathDelim;
  74. {$ENDIF}
  75. end;
  76. function DoTranslate(AId, AText: string): string;
  77. var
  78. item: TPOFileItem;
  79. begin
  80. if Assigned(FMainPoFile) then
  81. begin
  82. if AId <> '' then
  83. begin
  84. item := FMainPoFile.FindPoItem(AId);
  85. if Assigned(item) then
  86. exit(item.Translation);
  87. end;
  88. item := FMainPoFile.OriginalToItem(AText);
  89. if Assigned(item) then
  90. begin
  91. if item.Translation = '' then
  92. result := AText
  93. else
  94. exit(item.Translation);
  95. end;
  96. item := FMainPoFile.OriginalToItem(AText+':');
  97. if item = nil then item := FMainPoFile.OriginalToItem(AText+' :');
  98. if Assigned(item) then
  99. begin
  100. if item.Translation = '' then
  101. result := AText
  102. else
  103. result := item.Translation.TrimRight;
  104. if result.EndsWith(':') then
  105. begin
  106. delete(result, length(result), 1);
  107. result := result.TrimRight;
  108. end;
  109. exit;
  110. end;
  111. item := FMainPoFile.OriginalToItem(AText+'...');
  112. if Assigned(item) then
  113. begin
  114. if item.Translation = '' then
  115. result := AText
  116. else
  117. result := item.Translation.TrimRight;
  118. if result.EndsWith('...') then delete(result, length(result)-2, 3);
  119. exit;
  120. end;
  121. end;
  122. result := AText;
  123. end;
  124. function AppendQuestionMark(AText: string): string;
  125. begin
  126. if ActiveLanguage = 'es' then
  127. result := '¿'+AText+'?'
  128. else if ActiveLanguage = 'ar' then
  129. result := AText+'؟'
  130. else if (ActiveLanguage = 'fr') or (ActiveLanguage = 'kab') then
  131. result := Atext+' ?'
  132. else
  133. result := AText+'?';
  134. end;
  135. function LanguagePathUTF8: string;
  136. begin
  137. result := GetResourcePath('i18n');
  138. end;
  139. function LazPaintLanguageFile(ALanguage: string): string;
  140. begin
  141. result := 'lazpaint.'+ALanguage+'.po';
  142. end;
  143. function FallbackLanguage: string;
  144. var Lang,FallbackLang: string;
  145. begin
  146. Lang:='';
  147. FallbackLang:='';
  148. LazGetLanguageIDs(Lang,FallbackLang);
  149. result := FallbackLang;
  150. end;
  151. //translate program
  152. procedure TranslateLazPaint(AConfig: TIniFile);
  153. var
  154. POFile: String;
  155. Language: string;
  156. UpdatedLanguages: TStringList;
  157. begin
  158. Language := TLazPaintConfig.ClassGetDefaultLangage(AConfig);
  159. if Language = 'auto' then
  160. Language := FallBackLanguage;
  161. if Language = 'en' then exit;
  162. UpdatedLanguages := TStringList.Create;
  163. TLazPaintConfig.ClassGetUpdatedLanguages(UpdatedLanguages,AConfig,LazPaintVersionStr);
  164. if UpdatedLanguages.IndexOf(Language)<>-1 then
  165. POFile:=ActualConfigDirUTF8+LazPaintLanguageFile(Language) //updated file
  166. else
  167. POFile:='';
  168. if (POFile='') or not FileExistsUTF8(POFile) then
  169. POFile:=LanguagePathUTF8+LazPaintLanguageFile(Language); //default file
  170. UpdatedLanguages.Free;
  171. if FileExistsUTF8(POFile) then
  172. begin
  173. FMainPoFile := TPOFile.Create(POFile, true);
  174. LRSTranslator:=TPoTranslator.Create(FMainPoFile);
  175. TranslateResourceStrings(FMainPoFile);
  176. ActiveLanguage:= Language;
  177. end;
  178. POFile:=LanguagePathUTF8+'lclstrconsts.'+Language+'.po';
  179. if FileExistsUTF8(POFile) then
  180. Translations.TranslateUnitResourceStrings('LCLStrConsts',POFile);
  181. POFile:=LanguagePathUTF8+'lcresourcestring.'+Language+'.po';
  182. if FileExistsUTF8(POFile) then
  183. Translations.TranslateUnitResourceStrings('LCResourceString',POFile);
  184. end;
  185. //fill language list for configuration
  186. procedure FillLanguageList(AConfig: TLazPaintConfig);
  187. var
  188. dir : TSearchRec;
  189. idxDot: integer;
  190. language: string;
  191. i: integer;
  192. updatedLanguages: TStringList;
  193. begin
  194. AConfig.Languages.Add('en');
  195. if FindFirstUTF8(LanguagePathUTF8+'*.po',faAnyFile,dir) = 0 then
  196. repeat
  197. if (dir.Attr and (faDirectory or faVolumeId) = 0) and
  198. (copy(dir.name,1,9)='lazpaint.') then
  199. begin
  200. language := copy(dir.name,10,length(dir.name)-10+1);
  201. idxDot := pos('.',language);
  202. if idxDot <> 0 then
  203. begin
  204. language := copy(language,1,idxDot-1);
  205. AConfig.Languages.Add(language);
  206. end;
  207. end;
  208. until FindNextUTF8(dir)<>0;
  209. FindCloseUTF8(dir);
  210. updatedLanguages := TStringList.Create;
  211. AConfig.GetUpdatedLanguages(updatedLanguages);
  212. for i := 0 to updatedLanguages.Count-1 do
  213. begin
  214. if AConfig.Languages.IndexOf(updatedLanguages[i]) = -1 then
  215. AConfig.Languages.Add(updatedLanguages[i]);
  216. end;
  217. updatedLanguages.Free;
  218. AConfig.Languages.Sort;
  219. AConfig.Languages.Insert(0,'auto');
  220. end;
  221. initialization
  222. ActiveLanguage := DesignLanguage;
  223. end.