View Issue Details

IDProjectCategoryView StatusLast Update
0035543PatchesPackagespublic2019-06-28 18:41
ReporterYuriy SydorovAssigned ToMaxim Ganetsky 
PrioritynormalSeverityminorReproducibilityN/A
Status closedResolutionfixed 
Product Version2.1 (SVN)Product Build 
Target VersionFixed in Version2.2 
Summary0035543: [patch] Improve .pot/.po file generation and update
DescriptionThe applied patch improves the following:
- Automatically set the "object-pascal-format" flag for strings containing format chars. It allows tracking of format errors by external tools such as Poedit.
- The "no-object-pascal-format" flag can be specified for a string in the main .pot file if needed.
- It is possible to specify flags in the main .pot file for particular strings and these flags will be preserved and propagated to language specific .po files during the update.
- Fixed delimiter for flags. At least Poedit expects that flags are separated by comma and space, not just comma.
- TPOFileItem.ModifyFlag() can accept the comma separated list of flags and returns true if the Flags property has been modified.
TagsNo tags attached.
Fixed in Revision61225, 61226
LazTarget-
Widgetset
Attached Files
  • translations.pas.patch (4,701 bytes)
    Index: components/lazutils/translations.pas
    ===================================================================
    --- components/lazutils/translations.pas	(revision 60897)
    +++ components/lazutils/translations.pas	(working copy)
    @@ -98,7 +98,9 @@
         Context: string;
         Duplicate: boolean;
         constructor Create(const TheIdentifierLow, TheOriginal, TheTranslated: string);
    -    procedure ModifyFlag(const AFlag: string; Check: boolean);
    +    // Can accept the comma separated list of flags
    +    // Returns true if the Flags property has been modified
    +    function ModifyFlag(const AFlags: string; Check: boolean): boolean;
       end;
     
       { TPOFile }
    @@ -142,7 +144,7 @@
         procedure UpdateStrings(InputLines:TStrings; SType: TStringsType);
         procedure SaveToStrings(OutLst: TStrings);
         procedure SaveToFile(const AFilename: string);
    -    procedure UpdateItem(const Identifier: string; Original: string);
    +    procedure UpdateItem(const Identifier, Original: string; const Flags: string = '');
         procedure FillItem(var CurrentItem: TPOFileItem; Identifier, Original,
           Translation, Comments, Context, Flags, PreviousID: string; LineNr: Integer = -1);
         procedure UpdateTranslation(BasePOFile: TPOFile);
    @@ -206,6 +208,8 @@
     const
       sFuzzyFlag = 'fuzzy';
       sBadFormatFlag = 'badformat';
    +  sFormatFlag = 'object-pascal-format';
    +  sNoFormatFlag = 'no-object-pascal-format';
     
     
     implementation
    @@ -958,6 +962,7 @@
         while (LineStart^ in [#10,#13]) do inc(LineStart);
       end;
       AddEntry(LineNr);
    +  FModified := false;
     end;
     
     procedure TPOFile.RemoveIdentifiers(AIdentifiers: TStrings);
    @@ -1492,7 +1497,7 @@
       end;
     end;
     
    -procedure TPOFile.UpdateItem(const Identifier: string; Original: string);
    +procedure TPOFile.UpdateItem(const Identifier, Original: string; const Flags: string);
     var
       Item: TPOFileItem;
     begin
    @@ -1508,11 +1513,13 @@
             Item.ModifyFlag(sFuzzyFlag, true);
           end;
           Item.Original:=Original;
    +      if Flags <> '' then
    +        Item.ModifyFlag(Flags, true);
         end;
       end
       else // in this case new item will be added
         FModified := true;
    -  FillItem(Item, Identifier, Original, '', '', '', '', '');
    +  FillItem(Item, Identifier, Original, '', '', '', Flags, '');
     end;
     
     procedure TPOFile.FillItem(var CurrentItem: TPOFileItem; Identifier, Original,
    @@ -1521,6 +1528,7 @@
       function VerifyItemFormatting(var Item: TPOFileItem): boolean;
       var
         HasBadFormatFlag: boolean;
    +    i: integer;
       begin
         // this function verifies item formatting and sets its flags if the formatting is bad
         Result := true;
    @@ -1558,6 +1566,19 @@
             FModified := true;
           end;
         end;
    +
    +    if Item.Original <> '' then
    +    begin
    +      i:=0;
    +      if (ExtractFormatArgs(Item.Original, i) <> '') and (i = 0) then
    +      begin
    +        if Item.ModifyFlag(sFormatFlag, pos(sNoFormatFlag, Item.Flags) = 0) then
    +          FModified := true;
    +      end
    +      else
    +        if Item.ModifyFlag(sFormatFlag, false) then
    +          FModified := true;
    +    end;
       end;
     
     var
    @@ -1632,7 +1653,7 @@
       UntagAll;
       for i:=0 to BasePOFile.Items.Count-1 do begin
         Item := TPOFileItem(BasePOFile.Items[i]);
    -    UpdateItem(Item.IdentifierLow, Item.Original);
    +    UpdateItem(Item.IdentifierLow, Item.Original, Item.Flags);
       end;
       RemoveTaggedItems(0); // get rid of any item not existing in BasePOFile
       InvalidateStatistics;
    @@ -1694,23 +1715,56 @@
       Translation:=TheTranslated;
     end;
     
    -procedure TPOFileItem.ModifyFlag(const AFlag: string; Check: boolean);
    +function TPOFileItem.ModifyFlag(const AFlags: string; Check: boolean): boolean;
     var
    +  F, MF: TStringList;
    +
    +  procedure ProcessFlag(const AFlag: string);
    +  var
    +    i: Integer;
    +  begin
    +    i := F.IndexOf(AFlag);
    +    if (i<0) and Check then
    +    begin
    +      F.Add(AFlag);
    +      Result := true;
    +    end
    +    else
    +    begin
    +      if (i>=0) and (not Check) then
    +      begin
    +        F.Delete(i);
    +        Result := true;
    +      end;
    +    end;
    +  end;
    +
    +var
       i: Integer;
    -  F: TStringList;
     begin
    +  Result := false;
    +  MF := nil;
       F := TStringList.Create;
       try
         F.CommaText := Flags;
    -    i := F.IndexOf(AFlag);
    -    if (i<0) and Check then
    -      F.Add(AFlag)
    +
    +    if Pos(',', AFlags) = 0 then
    +      ProcessFlag(AFlags)
         else
    -    if (i>=0) and (not Check) then
    -      F.Delete(i);
    +    begin
    +      MF := TStringList.Create;
    +      MF.CommaText := AFlags;
    +      for i := 0 to MF.Count - 1 do
    +        ProcessFlag(MF[i]);
    +    end;
    +
    +    if not Result then
    +      exit;
         Flags := F.CommaText;
    +    Flags := StringReplace(Flags, ',', ', ', [rfReplaceAll]);
       finally
         F.Free;
    +    MF.Free;
       end;
     end;
     
    
    translations.pas.patch (4,701 bytes)

Activities

Yuriy Sydorov

2019-05-09 09:27

developer   ~0116097

Attached the updated patch.

translations.pas.patch (4,701 bytes)
Index: components/lazutils/translations.pas
===================================================================
--- components/lazutils/translations.pas	(revision 60897)
+++ components/lazutils/translations.pas	(working copy)
@@ -98,7 +98,9 @@
     Context: string;
     Duplicate: boolean;
     constructor Create(const TheIdentifierLow, TheOriginal, TheTranslated: string);
-    procedure ModifyFlag(const AFlag: string; Check: boolean);
+    // Can accept the comma separated list of flags
+    // Returns true if the Flags property has been modified
+    function ModifyFlag(const AFlags: string; Check: boolean): boolean;
   end;
 
   { TPOFile }
@@ -142,7 +144,7 @@
     procedure UpdateStrings(InputLines:TStrings; SType: TStringsType);
     procedure SaveToStrings(OutLst: TStrings);
     procedure SaveToFile(const AFilename: string);
-    procedure UpdateItem(const Identifier: string; Original: string);
+    procedure UpdateItem(const Identifier, Original: string; const Flags: string = '');
     procedure FillItem(var CurrentItem: TPOFileItem; Identifier, Original,
       Translation, Comments, Context, Flags, PreviousID: string; LineNr: Integer = -1);
     procedure UpdateTranslation(BasePOFile: TPOFile);
@@ -206,6 +208,8 @@
 const
   sFuzzyFlag = 'fuzzy';
   sBadFormatFlag = 'badformat';
+  sFormatFlag = 'object-pascal-format';
+  sNoFormatFlag = 'no-object-pascal-format';
 
 
 implementation
@@ -958,6 +962,7 @@
     while (LineStart^ in [#10,#13]) do inc(LineStart);
   end;
   AddEntry(LineNr);
+  FModified := false;
 end;
 
 procedure TPOFile.RemoveIdentifiers(AIdentifiers: TStrings);
@@ -1492,7 +1497,7 @@
   end;
 end;
 
-procedure TPOFile.UpdateItem(const Identifier: string; Original: string);
+procedure TPOFile.UpdateItem(const Identifier, Original: string; const Flags: string);
 var
   Item: TPOFileItem;
 begin
@@ -1508,11 +1513,13 @@
         Item.ModifyFlag(sFuzzyFlag, true);
       end;
       Item.Original:=Original;
+      if Flags <> '' then
+        Item.ModifyFlag(Flags, true);
     end;
   end
   else // in this case new item will be added
     FModified := true;
-  FillItem(Item, Identifier, Original, '', '', '', '', '');
+  FillItem(Item, Identifier, Original, '', '', '', Flags, '');
 end;
 
 procedure TPOFile.FillItem(var CurrentItem: TPOFileItem; Identifier, Original,
@@ -1521,6 +1528,7 @@
   function VerifyItemFormatting(var Item: TPOFileItem): boolean;
   var
     HasBadFormatFlag: boolean;
+    i: integer;
   begin
     // this function verifies item formatting and sets its flags if the formatting is bad
     Result := true;
@@ -1558,6 +1566,19 @@
         FModified := true;
       end;
     end;
+
+    if Item.Original <> '' then
+    begin
+      i:=0;
+      if (ExtractFormatArgs(Item.Original, i) <> '') and (i = 0) then
+      begin
+        if Item.ModifyFlag(sFormatFlag, pos(sNoFormatFlag, Item.Flags) = 0) then
+          FModified := true;
+      end
+      else
+        if Item.ModifyFlag(sFormatFlag, false) then
+          FModified := true;
+    end;
   end;
 
 var
@@ -1632,7 +1653,7 @@
   UntagAll;
   for i:=0 to BasePOFile.Items.Count-1 do begin
     Item := TPOFileItem(BasePOFile.Items[i]);
-    UpdateItem(Item.IdentifierLow, Item.Original);
+    UpdateItem(Item.IdentifierLow, Item.Original, Item.Flags);
   end;
   RemoveTaggedItems(0); // get rid of any item not existing in BasePOFile
   InvalidateStatistics;
@@ -1694,23 +1715,56 @@
   Translation:=TheTranslated;
 end;
 
-procedure TPOFileItem.ModifyFlag(const AFlag: string; Check: boolean);
+function TPOFileItem.ModifyFlag(const AFlags: string; Check: boolean): boolean;
 var
+  F, MF: TStringList;
+
+  procedure ProcessFlag(const AFlag: string);
+  var
+    i: Integer;
+  begin
+    i := F.IndexOf(AFlag);
+    if (i<0) and Check then
+    begin
+      F.Add(AFlag);
+      Result := true;
+    end
+    else
+    begin
+      if (i>=0) and (not Check) then
+      begin
+        F.Delete(i);
+        Result := true;
+      end;
+    end;
+  end;
+
+var
   i: Integer;
-  F: TStringList;
 begin
+  Result := false;
+  MF := nil;
   F := TStringList.Create;
   try
     F.CommaText := Flags;
-    i := F.IndexOf(AFlag);
-    if (i<0) and Check then
-      F.Add(AFlag)
+
+    if Pos(',', AFlags) = 0 then
+      ProcessFlag(AFlags)
     else
-    if (i>=0) and (not Check) then
-      F.Delete(i);
+    begin
+      MF := TStringList.Create;
+      MF.CommaText := AFlags;
+      for i := 0 to MF.Count - 1 do
+        ProcessFlag(MF[i]);
+    end;
+
+    if not Result then
+      exit;
     Flags := F.CommaText;
+    Flags := StringReplace(Flags, ',', ', ', [rfReplaceAll]);
   finally
     F.Free;
+    MF.Free;
   end;
 end;
 
translations.pas.patch (4,701 bytes)

Maxim Ganetsky

2019-05-14 01:28

developer   ~0116181

Applied, thanks!

All relevant translation files in IDE source tree have been regenerated in r61226.

Note that there can be spurious changes of PO files on first IDE rebuild. You can safely revert them. Also do not forget to rebuild updatepofiles tool if you use it.

Issue History

Date Modified Username Field Change
2019-05-08 17:40 Yuriy Sydorov New Issue
2019-05-08 17:40 Yuriy Sydorov File Added: translations.pas.patch
2019-05-09 09:26 Yuriy Sydorov File Deleted: translations.pas.patch
2019-05-09 09:27 Yuriy Sydorov File Added: translations.pas.patch
2019-05-09 09:27 Yuriy Sydorov Note Added: 0116097
2019-05-13 00:08 Maxim Ganetsky Assigned To => Maxim Ganetsky
2019-05-13 00:08 Maxim Ganetsky Status new => assigned
2019-05-14 01:28 Maxim Ganetsky Status assigned => resolved
2019-05-14 01:28 Maxim Ganetsky Resolution open => fixed
2019-05-14 01:28 Maxim Ganetsky Fixed in Version => 2.2
2019-05-14 01:28 Maxim Ganetsky Fixed in Revision => 61225, 61226
2019-05-14 01:28 Maxim Ganetsky LazTarget => -
2019-05-14 01:28 Maxim Ganetsky Note Added: 0116181
2019-06-28 18:41 Yuriy Sydorov Status resolved => closed