mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-08 09:38:12 +02:00
IDE: updating po files using codetools file caches
git-svn-id: trunk@34334 -
This commit is contained in:
parent
87b8887d73
commit
1b781cdb35
@ -32,7 +32,7 @@ interface
|
||||
uses
|
||||
Classes, SysUtils, GetText, LCLProc, Translations,
|
||||
IDEProcs, FileProcs, avl_tree,
|
||||
CodeToolManager, DirectoryCacher,
|
||||
CodeToolManager, DirectoryCacher, CodeCache,
|
||||
LazarusIDEStrConsts;
|
||||
{ IDE Language (Human, not computer) }
|
||||
|
||||
@ -64,6 +64,8 @@ type
|
||||
property Count: integer read FCount;
|
||||
property Items[Index: integer]: TLazarusTranslation read GetItems; default;
|
||||
end;
|
||||
|
||||
PPOFile = ^TPOFile;
|
||||
|
||||
// translate all resource strings
|
||||
procedure TranslateResourceStrings(const BaseDirectory, CustomLang: string);
|
||||
@ -77,6 +79,12 @@ procedure CollectTranslations(const LazarusDir: string);
|
||||
function ConvertRSTFiles(RSTDirectory, PODirectory: string;
|
||||
POFilename: string = '' // set POFilename to gather all rst into one po file
|
||||
): Boolean;
|
||||
procedure UpdatePoFileAndTranslations(SrcFiles: TStrings;
|
||||
const POFilename: string);
|
||||
procedure UpdateBasePoFile(SrcFiles: TStrings;
|
||||
const POFilename: string; POFile: PPOFile = nil);
|
||||
function FindTranslatedPoFiles(const BasePOFilename: string): TStringList;
|
||||
procedure UpdateTranslatedPoFile(const BasePOFile: TPOFile; TranslatedFilename: string);
|
||||
|
||||
var
|
||||
LazarusTranslations: TLazarusTranslations = nil;
|
||||
@ -250,7 +258,7 @@ begin
|
||||
for i:=0 to Items.Count-1 do begin
|
||||
Item:=PItem(Items[i]);
|
||||
if (not Item^.NeedUpdate) or (Item^.RSTFileList.Count=0) then continue;
|
||||
UpdatePoFile(Item^.RSTFileList, Item^.OutputFilename);
|
||||
UpdatePoFileAndTranslations(Item^.RSTFileList, Item^.OutputFilename);
|
||||
end;
|
||||
Result:=true;
|
||||
except
|
||||
@ -271,6 +279,148 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure UpdatePoFileAndTranslations(SrcFiles: TStrings;
|
||||
const POFilename: string);
|
||||
var
|
||||
BasePOFile: TPOFile;
|
||||
TranslatedFiles: TStringList;
|
||||
TranslatedFilename: String;
|
||||
begin
|
||||
BasePOFile:=nil;
|
||||
UpdateBasePoFile(SrcFiles,POFilename,@BasePOFile);
|
||||
if BasePOFile=nil then exit;
|
||||
TranslatedFiles:=nil;
|
||||
try
|
||||
TranslatedFiles:=FindTranslatedPoFiles(POFilename);
|
||||
if TranslatedFiles=nil then exit;
|
||||
for TranslatedFilename in TranslatedFiles do begin
|
||||
if FileAgeCached(TranslatedFilename)>=FileAgeCached(POFilename) then
|
||||
continue;
|
||||
UpdateTranslatedPoFile(BasePOFile,TranslatedFilename);
|
||||
end;
|
||||
finally
|
||||
TranslatedFiles.Free;
|
||||
BasePOFile.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure UpdateBasePoFile(SrcFiles: TStrings;
|
||||
const POFilename: string; POFile: PPOFile);
|
||||
var
|
||||
BasePOFile: TPOFile;
|
||||
i: Integer;
|
||||
Filename: String;
|
||||
POBuf: TCodeBuffer;
|
||||
FileType: TStringsType;
|
||||
SrcBuf: TCodeBuffer;
|
||||
SrcLines: TStringList;
|
||||
OldChangeStep: Integer;
|
||||
begin
|
||||
POBuf:=CodeToolBoss.LoadFile(POFilename,true,false);
|
||||
SrcLines:=TStringList.Create;
|
||||
BasePOFile := TPOFile.Create;
|
||||
try
|
||||
if POBuf<>nil then
|
||||
BasePOFile.ReadPOText(POBuf.Source);
|
||||
BasePOFile.Tag:=1;
|
||||
|
||||
// Update po file with lrt or/and rst files
|
||||
for i:=0 to SrcFiles.Count-1 do begin
|
||||
Filename:=SrcFiles[i];
|
||||
if CompareFileExt(Filename,'.lrt',false)=0 then
|
||||
FileType:=stLrt
|
||||
else if CompareFileExt(Filename,'.rst',false)=0 then
|
||||
FileType:=stRst
|
||||
else
|
||||
continue;
|
||||
SrcBuf:=CodeToolBoss.LoadFile(Filename,true,false);
|
||||
if SrcBuf=nil then continue;
|
||||
SrcLines.Text:=SrcBuf.Source;
|
||||
BasePOFile.UpdateStrings(SrcLines,FileType);
|
||||
end;
|
||||
SrcLines.Clear;
|
||||
BasePOFile.SaveToStrings(SrcLines);
|
||||
if POBuf=nil then begin
|
||||
POBuf:=CodeToolBoss.CreateFile(POFilename);
|
||||
if POBuf=nil then exit;
|
||||
end;
|
||||
OldChangeStep:=POBuf.ChangeStep;
|
||||
//debugln(['UpdateBasePoFile ',POFilename,' Modified=',POBuf.Source<>SrcLines.Text]);
|
||||
POBuf.Source:=SrcLines.Text;
|
||||
if (not POBuf.IsVirtual) and (OldChangeStep<>POBuf.ChangeStep) then begin
|
||||
debugln(['UpdateBasePoFile saving ',POBuf.Filename]);
|
||||
POBuf.Save;
|
||||
end;
|
||||
finally
|
||||
SrcLines.Free;
|
||||
if POFile<>nil then
|
||||
POFile^:=BasePOFile
|
||||
else
|
||||
BasePOFile.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
function FindTranslatedPoFiles(const BasePOFilename: string): TStringList;
|
||||
var
|
||||
Path: String;
|
||||
Name: String;
|
||||
NameOnly: String;
|
||||
Dir: TCTDirectoryCache;
|
||||
Files: TStrings;
|
||||
Filename: String;
|
||||
begin
|
||||
Result:=TStringList.Create;
|
||||
Path:=ExtractFilePath(BasePOFilename);
|
||||
Name:=ExtractFileName(BasePOFilename);
|
||||
NameOnly:=ExtractFileNameOnly(Name);
|
||||
Dir:=CodeToolBoss.DirectoryCachePool.GetCache(Path);
|
||||
Files:=TStringList.Create;
|
||||
try
|
||||
Dir.GetFiles(Files,false);
|
||||
for Filename in Files do begin
|
||||
if CompareFilenames(Filename,Name)=0 then continue;
|
||||
if CompareFileExt(Filename,'.po',false)<>0 then continue;
|
||||
if (CompareFilenames(LeftStr(Filename,length(NameOnly)),NameOnly)<>0)
|
||||
then
|
||||
continue;
|
||||
Result.Add(Path+Filename);
|
||||
end;
|
||||
finally
|
||||
Files.Free;
|
||||
Dir.Release;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure UpdateTranslatedPoFile(const BasePOFile: TPOFile;
|
||||
TranslatedFilename: string);
|
||||
var
|
||||
POBuf: TCodeBuffer;
|
||||
POFile: TPOFile;
|
||||
Lines: TStringList;
|
||||
OldChangeStep: Integer;
|
||||
begin
|
||||
POFile := TPOFile.Create;
|
||||
Lines:=TStringList.Create;
|
||||
try
|
||||
POBuf:=CodeToolBoss.LoadFile(TranslatedFilename,true,false);
|
||||
if POBuf<>nil then
|
||||
POFile.ReadPOText(POBuf.Source);
|
||||
POFile.Tag:=1;
|
||||
POFile.UpdateTranslation(BasePOFile);
|
||||
POFile.SaveToStrings(Lines);
|
||||
OldChangeStep:=POBuf.ChangeStep;
|
||||
//debugln(['UpdateTranslatedPoFile ',POBuf.Filename,' Modified=',POBuf.Source<>Lines.Text]);
|
||||
POBuf.Source:=Lines.Text;
|
||||
if (not POBuf.IsVirtual) and (OldChangeStep<>POBuf.ChangeStep) then begin
|
||||
//debugln(['UpdateTranslatedPoFile saving ',POBuf.Filename]);
|
||||
POBuf.Save;
|
||||
end;
|
||||
finally
|
||||
Lines.Free;
|
||||
POFile.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
{-------------------------------------------------------------------------------
|
||||
TranslateResourceStrings
|
||||
|
||||
|
@ -4365,7 +4365,7 @@ begin
|
||||
if Files.Tree.Count=0 then exit(mrOk);
|
||||
Files.GetNames(FileList);
|
||||
try
|
||||
UpdatePoFile(FileList, POFilename);
|
||||
UpdatePoFileAndTranslations(FileList, POFilename);
|
||||
Result := mrOk;
|
||||
except
|
||||
on E:EPOFileError do begin
|
||||
|
@ -124,6 +124,7 @@ type
|
||||
procedure Report;
|
||||
procedure CreateHeader;
|
||||
procedure UpdateStrings(InputLines:TStrings; SType: TStringsType);
|
||||
procedure SaveToStrings(OutLst: TStrings);
|
||||
procedure SaveToFile(const AFilename: string);
|
||||
procedure UpdateItem(const Identifier: string; Original: string);
|
||||
procedure UpdateTranslation(BasePOFile: TPOFile);
|
||||
@ -148,7 +149,6 @@ var
|
||||
// if you don't use UTF-8, install a proper widestring manager and set this
|
||||
// to false.
|
||||
|
||||
|
||||
// translate resource strings for one unit
|
||||
function TranslateUnitResourceStrings(const ResUnitName, BaseFilename,
|
||||
Lang, FallbackLang: string):TTranslateUnitResult; overload;
|
||||
@ -167,6 +167,12 @@ function UpdatePoFile(Files: TStrings; const POFilename: string): boolean;
|
||||
|
||||
implementation
|
||||
|
||||
function ComparePOItems(Item1, Item2: Pointer): Integer;
|
||||
begin
|
||||
Result := CompareText(TPOFileItem(Item1).IdentifierLow,
|
||||
TPOFileItem(Item2).IdentifierLow);
|
||||
end;
|
||||
|
||||
function UTF8ToSystemCharSet(const s: string): string; inline;
|
||||
begin
|
||||
if SystemCharSetIsUTF8 then
|
||||
@ -178,7 +184,6 @@ begin
|
||||
{$ENDIF}
|
||||
end;
|
||||
|
||||
|
||||
function StrToPoStr(const s:string):string;
|
||||
var
|
||||
SrcPos, DestPos: Integer;
|
||||
@ -975,32 +980,8 @@ begin
|
||||
RemoveUntaggedModules;
|
||||
end;
|
||||
|
||||
procedure TPOFile.RemoveTaggedItems(aTag: Integer);
|
||||
procedure TPOFile.SaveToStrings(OutLst: TStrings);
|
||||
var
|
||||
Item: TPOFileItem;
|
||||
i: Integer;
|
||||
begin
|
||||
// get rid of all entries that have Tag=aTag
|
||||
for i:=FItems.Count-1 downto 0 do begin
|
||||
Item := TPOFileItem(FItems[i]);
|
||||
if Item.Tag<>aTag then
|
||||
Continue;
|
||||
FIdentifierLowToItem.Remove(Item.IdentifierLow);
|
||||
//FOriginalToItem.Remove(Item.Original); // isn't this tricky?
|
||||
FItems.Delete(i);
|
||||
Item.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
function ComparePOItems(Item1, Item2: Pointer): Integer;
|
||||
begin
|
||||
result := CompareText(TPOFileItem(Item1).IdentifierLow,
|
||||
TPOFileItem(Item2).IdentifierLow);
|
||||
end;
|
||||
|
||||
procedure TPOFile.SaveToFile(const AFilename: string);
|
||||
var
|
||||
OutLst: TStringList;
|
||||
j: Integer;
|
||||
|
||||
procedure WriteLst(const AProp, AValue: string );
|
||||
@ -1010,7 +991,7 @@ var
|
||||
begin
|
||||
if (AValue='') and (AProp='') then
|
||||
exit;
|
||||
|
||||
|
||||
FHelperList.Text:=AValue;
|
||||
if FHelperList.Count=1 then begin
|
||||
if AProp='' then OutLst.Add(FHelperList[0])
|
||||
@ -1029,7 +1010,7 @@ var
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure WriteItem(Item: TPOFileItem);
|
||||
begin
|
||||
WriteLst('',Item.Comments);
|
||||
@ -1045,31 +1026,52 @@ var
|
||||
WriteLst('msgstr', StrToPoStr(Item.Translation));
|
||||
OutLst.Add('');
|
||||
end;
|
||||
|
||||
|
||||
begin
|
||||
if FHeader=nil then
|
||||
CreateHeader;
|
||||
|
||||
|
||||
if FHelperList=nil then
|
||||
FHelperList:=TStringList.Create;
|
||||
|
||||
|
||||
// write header
|
||||
WriteItem(FHeader);
|
||||
|
||||
// Sort list of items by identifier
|
||||
FItems.Sort(@ComparePOItems);
|
||||
|
||||
for j:=0 to Fitems.Count-1 do
|
||||
WriteItem(TPOFileItem(FItems[j]));
|
||||
end;
|
||||
|
||||
procedure TPOFile.RemoveTaggedItems(aTag: Integer);
|
||||
var
|
||||
Item: TPOFileItem;
|
||||
i: Integer;
|
||||
begin
|
||||
// get rid of all entries that have Tag=aTag
|
||||
for i:=FItems.Count-1 downto 0 do begin
|
||||
Item := TPOFileItem(FItems[i]);
|
||||
if Item.Tag<>aTag then
|
||||
Continue;
|
||||
FIdentifierLowToItem.Remove(Item.IdentifierLow);
|
||||
//FOriginalToItem.Remove(Item.Original); // isn't this tricky?
|
||||
FItems.Delete(i);
|
||||
Item.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TPOFile.SaveToFile(const AFilename: string);
|
||||
var
|
||||
OutLst: TStringList;
|
||||
begin
|
||||
OutLst := TStringList.Create;
|
||||
try
|
||||
// write header
|
||||
WriteItem(FHeader);
|
||||
|
||||
// Sort list of items by identifier
|
||||
FItems.Sort(@ComparePOItems);
|
||||
|
||||
for j:=0 to Fitems.Count-1 do
|
||||
WriteItem(TPOFileItem(FItems[j]));
|
||||
|
||||
SaveToStrings(OutLst);
|
||||
OutLst.SaveToFile(UTF8ToSys(AFilename));
|
||||
|
||||
finally
|
||||
OutLst.Free;
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
function SkipLineEndings(var P: PChar; var DecCount: Integer): Integer;
|
||||
|
Loading…
Reference in New Issue
Block a user