1 {
2 *****************************************************************************
3 * *
4 * This file is part of the ZCAD *
5 * *
6 * See the file COPYING.modifiedLGPL.txt, included in this distribution, *
7 * for details about the copyright. *
8 * *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
12 * *
13 *****************************************************************************
14 }
15 {
16 @author(Andrey Zubarev <zamtmn@yandex.ru>)
17 }
18
19 unit uzctranslations;
20 {$INCLUDE def.inc}
21
22 interface
23 uses uzbpaths,LCLVersion,uzbstrproc{$IFNDEF DELPHI},LazUTF8,gettext,translations,
24 fileutil,LResources{$ENDIF},uzcsysinfo,sysutils,uzclog,forms,Classes, typinfo,
25 uzcsysparams,LazLogger;
26
27 const
28 ZCADTranslatedPOFileName='zcad.%s.po';
29 ZCADPOFileName='zcad.po';
30 ZCADRTTranslatedPOFileName='rtzcad.%s.po';
31 ZCADRTPOFileName='rtzcad.po';
32 ZCADRTBackupPOFileName='rtzcad.po.backup';
33 type
34 TmyPOFile = class(TPOFile)
FindByIdentifiernull35 function FindByIdentifier(const Identifier: String):TPOFileItem;
36 procedure SaveToFile(const AFilename: string);
37 {$IF LCL_FULLVERSION<1030000}
38 procedure Add(const Identifier, OriginalValue, TranslatedValue, Comments,
39 Context, Flags, PreviousID: string);
40 {$ENDIF}
41 {$IF LCL_FULLVERSION>=1030000}
42 procedure Add(const Identifier, OriginalValue, TranslatedValue,
43 Comments, Context, Flags, PreviousID: string; SetFuzzy: boolean = false; LineNr: Integer = -1);
44 {$ENDIF}
Translatenull45 function Translate(const Identifier, OriginalValue: String): String;
exportcompileritemsnull46 function exportcompileritems(sourcepo:TPOFile):integer;
47 end;
48 TPoTranslator=class(TAbstractTranslator)
49 public
50 procedure TranslateStringProperty(Sender:TObject;
51 const Instance: TPersistent; PropInfo: PPropInfo; var Content:string);override;
52 end;
53
InterfaceTranslatenull54 function InterfaceTranslate(const Identifier, OriginalValue: String): String;
55 procedure DisableTranslate;
56 procedure EnableTranslate;
57 var
58 PODirectory, Lang, FallbackLang: AnsiString;
59 po: TmyPOFile;
60 actualypo: TmyPOFile;
61 _UpdatePO:integer=0;
62 _NotEnlishWord:integer=0;
63 _DebugWord:integer=0;
64 DisableTranslateCount:integer;
65 const
66 identpref='zcadexternal.';
67 implementation
68 var
69 TranslateLogModuleId:TLogModuleDeskIndex;
70 procedure DisableTranslate;
71 begin
72 inc(DisableTranslateCount);
73 end;
74 procedure EnableTranslate;
75 begin
76 dec(DisableTranslateCount);
77 end;
78 procedure TPoTranslator.TranslateStringProperty(Sender: TObject;
79 const Instance: TPersistent; PropInfo: PPropInfo; var Content: string);
80 var
81 s: String;
82 begin
83 if not Assigned(po) then exit;
84 if not Assigned(PropInfo) then exit;
85 {Нужно ли нам это?}
86 if Instance is TComponent then
87 if csDesigning in (Instance as TComponent).ComponentState then exit;
88 {:)}
89 if (AnsiUpperCase(PropInfo^.PropType^.Name)<>'TTRANSLATESTRING') then exit;
90 s:=po.Translate(Content, Content);
91 if s<>'' then Content:=s;
92 end;
93
FindByIdentifiernull94 function TmyPOFile.FindByIdentifier(const Identifier: String):TPOFileItem;
95 begin
96 result:=FindPoItem(Identifier);
97 //uncoment for lazarus < r57491
98 //result:=TPOFileItem({FIdentifierToItem}FIdentLowVarToItem.Data[Identifier]);
99 end;
100 procedure TmyPOFile.SaveToFile(const AFilename: string);
101 begin
102 inherited//self.f
103 end;
exportcompileritemsnull104 function TmyPOFile.exportcompileritems(sourcepo:TPOFile):integer;
105 var
106 j:integer;
107 ident:string;
108 Item,NewItem: TPOFileItem;
109 begin
110 for j:=0 to Fitems.Count-1 do
111 begin
112 item:=TPOFileItem(FItems[j]);
113 ident:=item.IdentifierLow;
114 if (pos('~',ident)<=0)
115 and(pos('.',ident)>0) then
116 begin
117 NewItem:=nil;
118 sourcepo.FillItem(NewItem,ident, item.Original, item.Translation, item.Comments,
119 item.Context, item.Flags,'');
120 //uncoment if Lazarus<r57425
121 //sourcepo.Add(ident, item.Original, item.Translation, item.Comments,
122 // item.Context, item.Flags,'');
123 end;
124 end;
125 result:=items.Count-sourcepo.items.Count;
126 end;
TmyPOFile.Translatenull127 function TmyPOFile.Translate(const Identifier, OriginalValue: String): String;
128 var
129 Item: TPOFileItem;
130 begin
131 Item:=FindPoItem(Identifier);
132 //uncoment for lazarus < r57491
133 //Item:=TPOFileItem({FIdentifierToItem}FIdentLowVarToItem.Data[Identifier]);
134 if Item=nil then
135 Item:=TPOFileItem(FOriginalToItem.Data[OriginalValue]);
136 if Item<>nil then begin
137 Result:=Item.Translation;
138 if Result='' then Result:=OriginalValue;
139 end else
140 Result:=OriginalValue;
141 end;
142 procedure TmyPOFile.Add(const Identifier, OriginalValue, TranslatedValue,
143 Comments, Context, Flags, PreviousID: string; SetFuzzy: boolean = false; LineNr: Integer = -1);
144 var
145 t:boolean;
146 NewItem:TPOFileItem;
147 begin
148 t:=self.FAllEntries;
149 self.FAllEntries:=true;
150 NewItem:=nil;
151 FillItem(NewItem,Identifier, OriginalValue, TranslatedValue, Comments,Context, Flags, PreviousID);
152 //uncoment if Lazarus<r57425
153 //inherited Add(Identifier, OriginalValue, TranslatedValue, Comments,Context, Flags, PreviousID);
154 self.FAllEntries:=t;
155 end;
156
157 procedure createpo;
158 var
159 AFilename:string;
160 begin
161 if not sysparam.saved.updatepo then
162 begin
163 if Lang<>'' then
164 begin
165 AFilename:=Format(PODirectory + ZCADRTTranslatedPOFileName,[Lang]);
166 if FileExists{UTF8}(AFilename) then
167 begin
168 po:=TmyPOFile.Create(AFilename);
169 end;
170 end;
171 if (FallbackLang<>'')and(not assigned(po)) then
172 begin
173 AFilename:=Format(PODirectory + ZCADRTTranslatedPOFileName,[FallbackLang]);
174 if FileExists{UTF8}(AFilename) then
175 begin
176 po:=TmyPOFile.Create(AFilename);
177 end;
178 end;
179 if (not assigned(po)) then
180 begin
181 po:=TmyPOFile.Create;
182 end;
183
184 end
185 else
186 begin
187 AFilename:=(PODirectory + ZCADRTPOFileName);
188 if FileExists{UTF8}(AFilename) then
189 begin
190 po:=TmyPOFile.Create(AFilename,true);
191 actualypo:=TmyPOFile.Create;
192 end
193 else
194 begin
195 programlog.LogOutStr('Founf command line swith "UpdatePO". File "zcad.po" not found. STOP!',0,LM_Fatal);
196 halt(0);
197 end;
198 end;
199 end;
InterfaceTranslatenull200 function InterfaceTranslate( const Identifier, OriginalValue: String): String;
201 const nontranslatedword='InterfaceTranslate: found not translated word: identifier:"%s" originalValue:"%s"';
202 var
203 Item: TPOFileItem;
204 begin
205 if DisableTranslateCount>0 then
206 begin
207 result:=OriginalValue;
208 exit;
209 end;
210 result:=po.Translate(Identifier, OriginalValue);
211 programlog.LogOutFormatStr('InterfaceTranslate: identifier:"%s" originalValue:"%s" translate to "%s"',[Identifier,OriginalValue,result],0,LM_Debug,TranslateLogModuleId);
212
213 if sysparam.saved.updatepo then
214 begin
215 Item:=po.FindPoItem(Identifier);
216 //uncoment for lazarus < r57491
217 //Item:=TPOFileItem(po.{FIdentifierToItem}FIdentLowVarToItem{FOriginalToItem}.Data[UTF8LowerCase(Identifier)]);
218 if not assigned(item) then
219 begin
220 if (pos('**',OriginalValue)>0)or(pos('??',OriginalValue)>0)or(pos('__',OriginalValue)=1)then
221 begin
222 inc(_DebugWord);
223 programlog.LogOutStr(format('InterfaceTranslate: found debug word: identifier:"%s" originalValue:"%s"',[Identifier,OriginalValue]),0,LM_Warning,TranslateLogModuleId);
224 end
225 else
226 begin
227 if (utf8length(Identifier)=length(Identifier))and
228 (utf8length(OriginalValue)=length(OriginalValue)) then
229 begin
230 if pos(identpref,Identifier)<>1 then
231 begin
232 programlog.LogOutStr(format(nontranslatedword,[Identifier,OriginalValue]),0,LM_Warning,TranslateLogModuleId);
233 po.Add(identpref+Identifier,OriginalValue, {TranslatedValue}'', {Comments}'',{Context}'', {Flags}'', {PreviousID}'');
234 actualypo.Add(identpref+Identifier,OriginalValue, {TranslatedValue}'', {Comments}'',{Context}'', {Flags}'', {PreviousID}'');
235 end
236 else
237 begin
238 programlog.LogOutStr(format(nontranslatedword,[Identifier,OriginalValue]),0,LM_Warning,TranslateLogModuleId);
239 po.Add(Identifier,OriginalValue, {TranslatedValue}'', {Comments}'',{Context}'', {Flags}'', {PreviousID}'');
240 actualypo.Add(Identifier,OriginalValue, {TranslatedValue}'', {Comments}'',{Context}'', {Flags}'', {PreviousID}'');
241 end;
242 inc(_UpdatePO);
243 //po.SaveToFile(PODirectory + 'zcad.po');
244 end
245 else
246 begin
247 inc(_NotEnlishWord);
248 programlog.LogOutStr(format('InterfaceTranslate: found non ASCII word: identifier:"%s" originalValue:"%s"',[Identifier,OriginalValue]),0,LM_Warning,TranslateLogModuleId);
249 //log.LogOut(Identifier+'--------------'+OriginalValue)
250 end;
251
252 end;
253 end
254 else
255 begin
256 if item.Original<>OriginalValue then
257 begin
258 item.ModifyFlag('fuzzy',true);
259 item.Original:=OriginalValue;
260 end;
261 actualypo.Add({identpref+}item.IdentifierLow, item.Original, item.Translation, item.Comments,
262 item.Context, item.Flags,'');
263 end;
264
265 end;
266 end;
267
268 procedure initialize;
269 begin
270 DisableTranslateCount:=0;
271 PODirectory := ProgramPath+'languages/';
272 GetLanguageIDs(Lang, FallbackLang); // определено в модуле gettext
273 createpo;
274 LRSTranslator:=TPoTranslator.Create;
275 if not sysparam.saved.updatepo then
276 begin
277 TranslateResourceStrings(PODirectory + ZCADTranslatedPOFileName, Lang, FallbackLang);
278 TranslateUnitResourceStrings('anchordockstr', PODirectory + 'anchordockstr.%s.po', Lang, FallbackLang);
279 TranslateUnitResourceStrings('lclstrconsts', PODirectory + 'lclstrconsts.%S.po', Lang, FallbackLang);
280 end;
281 end;
282
283 initialization
284 TranslateLogModuleId:=programlog.registermodule('TRANSLATOR');
285 initialize;
286 finalization
287 debugln('{I}[UnitsFinalization] Unit "',{$INCLUDE %FILE%},'" finalization');
288 if assigned(actualypo) then freeandnil(actualypo);
289 if assigned(po) then freeandnil(po);
290 if assigned(LRSTranslator) then freeandnil(LRSTranslator);
291 end.
292