mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-06-07 20:38:30 +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
|
uses
|
||||||
Classes, SysUtils, GetText, LCLProc, Translations,
|
Classes, SysUtils, GetText, LCLProc, Translations,
|
||||||
IDEProcs, FileProcs, avl_tree,
|
IDEProcs, FileProcs, avl_tree,
|
||||||
CodeToolManager, DirectoryCacher,
|
CodeToolManager, DirectoryCacher, CodeCache,
|
||||||
LazarusIDEStrConsts;
|
LazarusIDEStrConsts;
|
||||||
{ IDE Language (Human, not computer) }
|
{ IDE Language (Human, not computer) }
|
||||||
|
|
||||||
@ -65,6 +65,8 @@ type
|
|||||||
property Items[Index: integer]: TLazarusTranslation read GetItems; default;
|
property Items[Index: integer]: TLazarusTranslation read GetItems; default;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
PPOFile = ^TPOFile;
|
||||||
|
|
||||||
// translate all resource strings
|
// translate all resource strings
|
||||||
procedure TranslateResourceStrings(const BaseDirectory, CustomLang: string);
|
procedure TranslateResourceStrings(const BaseDirectory, CustomLang: string);
|
||||||
|
|
||||||
@ -77,6 +79,12 @@ procedure CollectTranslations(const LazarusDir: string);
|
|||||||
function ConvertRSTFiles(RSTDirectory, PODirectory: string;
|
function ConvertRSTFiles(RSTDirectory, PODirectory: string;
|
||||||
POFilename: string = '' // set POFilename to gather all rst into one po file
|
POFilename: string = '' // set POFilename to gather all rst into one po file
|
||||||
): Boolean;
|
): 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
|
var
|
||||||
LazarusTranslations: TLazarusTranslations = nil;
|
LazarusTranslations: TLazarusTranslations = nil;
|
||||||
@ -250,7 +258,7 @@ begin
|
|||||||
for i:=0 to Items.Count-1 do begin
|
for i:=0 to Items.Count-1 do begin
|
||||||
Item:=PItem(Items[i]);
|
Item:=PItem(Items[i]);
|
||||||
if (not Item^.NeedUpdate) or (Item^.RSTFileList.Count=0) then continue;
|
if (not Item^.NeedUpdate) or (Item^.RSTFileList.Count=0) then continue;
|
||||||
UpdatePoFile(Item^.RSTFileList, Item^.OutputFilename);
|
UpdatePoFileAndTranslations(Item^.RSTFileList, Item^.OutputFilename);
|
||||||
end;
|
end;
|
||||||
Result:=true;
|
Result:=true;
|
||||||
except
|
except
|
||||||
@ -271,6 +279,148 @@ begin
|
|||||||
end;
|
end;
|
||||||
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
|
TranslateResourceStrings
|
||||||
|
|
||||||
|
@ -4365,7 +4365,7 @@ begin
|
|||||||
if Files.Tree.Count=0 then exit(mrOk);
|
if Files.Tree.Count=0 then exit(mrOk);
|
||||||
Files.GetNames(FileList);
|
Files.GetNames(FileList);
|
||||||
try
|
try
|
||||||
UpdatePoFile(FileList, POFilename);
|
UpdatePoFileAndTranslations(FileList, POFilename);
|
||||||
Result := mrOk;
|
Result := mrOk;
|
||||||
except
|
except
|
||||||
on E:EPOFileError do begin
|
on E:EPOFileError do begin
|
||||||
|
@ -124,6 +124,7 @@ type
|
|||||||
procedure Report;
|
procedure Report;
|
||||||
procedure CreateHeader;
|
procedure CreateHeader;
|
||||||
procedure UpdateStrings(InputLines:TStrings; SType: TStringsType);
|
procedure UpdateStrings(InputLines:TStrings; SType: TStringsType);
|
||||||
|
procedure SaveToStrings(OutLst: TStrings);
|
||||||
procedure SaveToFile(const AFilename: string);
|
procedure SaveToFile(const AFilename: string);
|
||||||
procedure UpdateItem(const Identifier: string; Original: string);
|
procedure UpdateItem(const Identifier: string; Original: string);
|
||||||
procedure UpdateTranslation(BasePOFile: TPOFile);
|
procedure UpdateTranslation(BasePOFile: TPOFile);
|
||||||
@ -148,7 +149,6 @@ var
|
|||||||
// if you don't use UTF-8, install a proper widestring manager and set this
|
// if you don't use UTF-8, install a proper widestring manager and set this
|
||||||
// to false.
|
// to false.
|
||||||
|
|
||||||
|
|
||||||
// translate resource strings for one unit
|
// translate resource strings for one unit
|
||||||
function TranslateUnitResourceStrings(const ResUnitName, BaseFilename,
|
function TranslateUnitResourceStrings(const ResUnitName, BaseFilename,
|
||||||
Lang, FallbackLang: string):TTranslateUnitResult; overload;
|
Lang, FallbackLang: string):TTranslateUnitResult; overload;
|
||||||
@ -167,6 +167,12 @@ function UpdatePoFile(Files: TStrings; const POFilename: string): boolean;
|
|||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
|
function ComparePOItems(Item1, Item2: Pointer): Integer;
|
||||||
|
begin
|
||||||
|
Result := CompareText(TPOFileItem(Item1).IdentifierLow,
|
||||||
|
TPOFileItem(Item2).IdentifierLow);
|
||||||
|
end;
|
||||||
|
|
||||||
function UTF8ToSystemCharSet(const s: string): string; inline;
|
function UTF8ToSystemCharSet(const s: string): string; inline;
|
||||||
begin
|
begin
|
||||||
if SystemCharSetIsUTF8 then
|
if SystemCharSetIsUTF8 then
|
||||||
@ -178,7 +184,6 @@ begin
|
|||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
function StrToPoStr(const s:string):string;
|
function StrToPoStr(const s:string):string;
|
||||||
var
|
var
|
||||||
SrcPos, DestPos: Integer;
|
SrcPos, DestPos: Integer;
|
||||||
@ -975,32 +980,8 @@ begin
|
|||||||
RemoveUntaggedModules;
|
RemoveUntaggedModules;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TPOFile.RemoveTaggedItems(aTag: Integer);
|
procedure TPOFile.SaveToStrings(OutLst: TStrings);
|
||||||
var
|
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;
|
j: Integer;
|
||||||
|
|
||||||
procedure WriteLst(const AProp, AValue: string );
|
procedure WriteLst(const AProp, AValue: string );
|
||||||
@ -1053,23 +1034,44 @@ begin
|
|||||||
if FHelperList=nil then
|
if FHelperList=nil then
|
||||||
FHelperList:=TStringList.Create;
|
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;
|
OutLst := TStringList.Create;
|
||||||
try
|
try
|
||||||
// write header
|
SaveToStrings(OutLst);
|
||||||
WriteItem(FHeader);
|
|
||||||
|
|
||||||
// Sort list of items by identifier
|
|
||||||
FItems.Sort(@ComparePOItems);
|
|
||||||
|
|
||||||
for j:=0 to Fitems.Count-1 do
|
|
||||||
WriteItem(TPOFileItem(FItems[j]));
|
|
||||||
|
|
||||||
OutLst.SaveToFile(UTF8ToSys(AFilename));
|
OutLst.SaveToFile(UTF8ToSys(AFilename));
|
||||||
|
|
||||||
finally
|
finally
|
||||||
OutLst.Free;
|
OutLst.Free;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function SkipLineEndings(var P: PChar; var DecCount: Integer): Integer;
|
function SkipLineEndings(var P: PChar; var DecCount: Integer): Integer;
|
||||||
|
Loading…
Reference in New Issue
Block a user