View Issue Details

IDProjectCategoryView StatusLast Update
0034836LazarusLCLpublic2019-01-17 11:16
ReporterAlfredAssigned ToMaxim Ganetsky 
PrioritynormalSeverityminorReproducibilityN/A
Status closedResolutionfixed 
Product Version2.1 (SVN)Product Build 
Target VersionFixed in Version2.2 
Summary0034836: Let lcltranslater use a custom app name.
DescriptionFpcupdeluxe uses a macro to create custom app names for different cpu and os:
-o bin\$NameOnly($(ProjFile))-$(TargetCPU)-$(TargetOS)

There have been requests to add (i18n) language support.

The lcltranslator uses paramstr(0) as binary name to find language-files.
Due to the binaries having different names, this does not work that well.

Th patch makes it possible to define a basic language file name.
TagsNo tags attached.
Fixed in Revision60097
LazTarget-
Widgetset
Attached Files
  • REV60026.diff (3,658 bytes)
    Index: lcl/lcltranslator.pas
    ===================================================================
    --- lcl/lcltranslator.pas	(revision 60026)
    +++ lcl/lcltranslator.pas	(working copy)
    @@ -80,7 +80,7 @@
           PropInfo: PPropInfo; var Content: string); override;
       end;
     
    -procedure SetDefaultLang(Lang: string; Dir: string = ''; ForceUpdate: boolean = true);
    +procedure SetDefaultLang(Lang: string; Dir: string = ''; ForceUpdate: boolean = true; LocaleFileName: string = '');
     function GetDefaultLang: String;
     
     implementation
    @@ -92,12 +92,12 @@
     var
       DefaultLang: String = '';
     
    -function FindLocaleFileName(LCExt: string; Lang: string; Dir: string): string;
    +function FindLocaleFileName(LCExt: string; Lang: string; Dir: string; LocaleFileName: string): string;
     var
       T: string;
       i: integer;
     
    -  function GetLocaleFileName(const LangID, LCExt: string; Dir: string): string;
    +  function GetLocaleFileName(const LangID, LCExt: string; Dir: string; LocaleFileName: string): string;
       var
         LangShortID: string;
         AppDir,LCFileName,FullLCFileName: String;
    @@ -106,11 +106,17 @@
         DefaultLang := LangID;
     
         AppDir := ExtractFilePath(ParamStrUTF8(0));
    -    LCFileName := ChangeFileExt(ExtractFileName(ParamStrUTF8(0)), LCExt);
    +    if LocaleFileName = '' then
    +      LCFileName := ChangeFileExt(ExtractFileName(ParamStrUTF8(0)), LCExt)
    +    else
    +      LCFileName := ChangeFileExt(LocaleFileName, LCExt);
     
         if LangID <> '' then
         begin
    -      FullLCFileName := ChangeFileExt(ExtractFileName(ParamStrUTF8(0)), '.' + LangID) + LCExt;
    +      if LocaleFileName = '' then
    +        FullLCFileName := ChangeFileExt(ExtractFileName(ParamStrUTF8(0)), '.' + LangID) + LCExt
    +      else
    +        FullLCFileName := ChangeFileExt(LocaleFileName, '.' + LangID) + LCExt;
     
           if Dir<>'' then
           begin
    @@ -219,7 +225,10 @@
             exit;
           {$ENDIF}
     
    -      FullLCFileName := ChangeFileExt(ExtractFileName(ParamStrUTF8(0)), '.' + LangShortID) + LCExt;
    +      if LocaleFileName = '' then
    +        FullLCFileName := ChangeFileExt(ExtractFileName(ParamStrUTF8(0)), '.' + LangShortID) + LCExt
    +      else
    +        FullLCFileName := ChangeFileExt(LocaleFileName, '.' + LangShortID) + LCExt;
     
           if Dir<>'' then
           begin
    @@ -276,7 +285,7 @@
       if Lang = '' then
         LazGetLanguageIDs(Lang, T);
     
    -  Result := GetLocaleFileName(Lang, LCExt, Dir);
    +  Result := GetLocaleFileName(Lang, LCExt, Dir, LocaleFileName);
     end;
     
     function GetIdentifierPath(Sender: TObject;
    @@ -502,7 +511,7 @@
       end;
     end;
     
    -procedure SetDefaultLang(Lang: string; Dir: string = ''; ForceUpdate: boolean = true);
    +procedure SetDefaultLang(Lang: string; Dir: string = ''; ForceUpdate: boolean = true; LocaleFileName: string = '');
     { Arguments:
       Lang - language (e.g. 'ru', 'de'); empty argument is default language.
       Dir - custom translation files subdirectory (e.g. 'mylng'); empty argument means searching only in predefined subdirectories.
    @@ -519,7 +528,7 @@
       LocalTranslator := nil;
       // search first po translation resources
       try
    -     lcfn := FindLocaleFileName('.po', Lang, Dir);
    +     lcfn := FindLocaleFileName('.po', Lang, Dir, LocaleFileName);
          if lcfn <> '' then
          begin
            Translations.TranslateResourceStrings(lcfn);
    @@ -541,7 +550,7 @@
       begin
         // try now with MO translation resources
         try
    -      lcfn := FindLocaleFileName('.mo', Lang, Dir);
    +      lcfn := FindLocaleFileName('.mo', Lang, Dir, LocaleFileName);
           if lcfn <> '' then
           begin
             GetText.TranslateResourceStrings(UTF8ToSys(lcfn));
    
    REV60026.diff (3,658 bytes)

Activities

Alfred

2019-01-08 08:01

reporter  

REV60026.diff (3,658 bytes)
Index: lcl/lcltranslator.pas
===================================================================
--- lcl/lcltranslator.pas	(revision 60026)
+++ lcl/lcltranslator.pas	(working copy)
@@ -80,7 +80,7 @@
       PropInfo: PPropInfo; var Content: string); override;
   end;
 
-procedure SetDefaultLang(Lang: string; Dir: string = ''; ForceUpdate: boolean = true);
+procedure SetDefaultLang(Lang: string; Dir: string = ''; ForceUpdate: boolean = true; LocaleFileName: string = '');
 function GetDefaultLang: String;
 
 implementation
@@ -92,12 +92,12 @@
 var
   DefaultLang: String = '';
 
-function FindLocaleFileName(LCExt: string; Lang: string; Dir: string): string;
+function FindLocaleFileName(LCExt: string; Lang: string; Dir: string; LocaleFileName: string): string;
 var
   T: string;
   i: integer;
 
-  function GetLocaleFileName(const LangID, LCExt: string; Dir: string): string;
+  function GetLocaleFileName(const LangID, LCExt: string; Dir: string; LocaleFileName: string): string;
   var
     LangShortID: string;
     AppDir,LCFileName,FullLCFileName: String;
@@ -106,11 +106,17 @@
     DefaultLang := LangID;
 
     AppDir := ExtractFilePath(ParamStrUTF8(0));
-    LCFileName := ChangeFileExt(ExtractFileName(ParamStrUTF8(0)), LCExt);
+    if LocaleFileName = '' then
+      LCFileName := ChangeFileExt(ExtractFileName(ParamStrUTF8(0)), LCExt)
+    else
+      LCFileName := ChangeFileExt(LocaleFileName, LCExt);
 
     if LangID <> '' then
     begin
-      FullLCFileName := ChangeFileExt(ExtractFileName(ParamStrUTF8(0)), '.' + LangID) + LCExt;
+      if LocaleFileName = '' then
+        FullLCFileName := ChangeFileExt(ExtractFileName(ParamStrUTF8(0)), '.' + LangID) + LCExt
+      else
+        FullLCFileName := ChangeFileExt(LocaleFileName, '.' + LangID) + LCExt;
 
       if Dir<>'' then
       begin
@@ -219,7 +225,10 @@
         exit;
       {$ENDIF}
 
-      FullLCFileName := ChangeFileExt(ExtractFileName(ParamStrUTF8(0)), '.' + LangShortID) + LCExt;
+      if LocaleFileName = '' then
+        FullLCFileName := ChangeFileExt(ExtractFileName(ParamStrUTF8(0)), '.' + LangShortID) + LCExt
+      else
+        FullLCFileName := ChangeFileExt(LocaleFileName, '.' + LangShortID) + LCExt;
 
       if Dir<>'' then
       begin
@@ -276,7 +285,7 @@
   if Lang = '' then
     LazGetLanguageIDs(Lang, T);
 
-  Result := GetLocaleFileName(Lang, LCExt, Dir);
+  Result := GetLocaleFileName(Lang, LCExt, Dir, LocaleFileName);
 end;
 
 function GetIdentifierPath(Sender: TObject;
@@ -502,7 +511,7 @@
   end;
 end;
 
-procedure SetDefaultLang(Lang: string; Dir: string = ''; ForceUpdate: boolean = true);
+procedure SetDefaultLang(Lang: string; Dir: string = ''; ForceUpdate: boolean = true; LocaleFileName: string = '');
 { Arguments:
   Lang - language (e.g. 'ru', 'de'); empty argument is default language.
   Dir - custom translation files subdirectory (e.g. 'mylng'); empty argument means searching only in predefined subdirectories.
@@ -519,7 +528,7 @@
   LocalTranslator := nil;
   // search first po translation resources
   try
-     lcfn := FindLocaleFileName('.po', Lang, Dir);
+     lcfn := FindLocaleFileName('.po', Lang, Dir, LocaleFileName);
      if lcfn <> '' then
      begin
        Translations.TranslateResourceStrings(lcfn);
@@ -541,7 +550,7 @@
   begin
     // try now with MO translation resources
     try
-      lcfn := FindLocaleFileName('.mo', Lang, Dir);
+      lcfn := FindLocaleFileName('.mo', Lang, Dir, LocaleFileName);
       if lcfn <> '' then
       begin
         GetText.TranslateResourceStrings(UTF8ToSys(lcfn));
REV60026.diff (3,658 bytes)

Alfred

2019-01-08 08:02

reporter   ~0113257

Usage:
SetDefaultLang('zh_cn','',true,'fpcupdeluxe');

Maxim Ganetsky

2019-01-08 22:16

developer   ~0113275

To be honest, I don't like this proposal.

First, IMHO, it is wrong to meddle with executables names in the first place, better place them in different directories.

Second, your patch introduces a new parameter which is quite incomprehensible in normal use cases. Thus it is very likely, that it will be used (let alone properly used) only in a minority of cases, and this means that most programs will suffer from this problem anyway even with this patch applied.

Alternative is adding some heuristics to detect and discard patform part of the name, but I am not sure that it is not over the top for LCLTranslator unit.

Alfred

2019-01-09 07:41

reporter   ~0113279

I agree with the fact that heuristics will be over the top. And heuristics can have unwanted side-effect, because they will influence all users of the translator unit. So, that is not the way to go.

My patch should not have any influence on the normal use of SetDefaultLang, due to the fact that it is backwards compatible.

For me, it would be logical that, if you are able to set a language file name part by e.g. 'zh_cn' and a language directory, you should also be able to set the default language file denominator, in stead of just using paramstr(0).

wp

2019-01-09 09:20

developer   ~0113282

I like the idea of giving the language file a name different from the application name.

Maxim Ganetsky

2019-01-17 01:15

developer   ~0113443

I made implementation of your suggestion based on your patch, thanks.

Note that SetDefaultLang signature was changed in somewhat incompatible way in order to not force users specify 'obscure' ForceUpdate parameter if they only want to set translation name, so the usage will be:

SetDefaultLang('zh_cn','','fpcupdeluxe');

This incompatibility only affects the users who called SetDefaultLang from unit initialization section and thus needed to set ForceUpdate parameter to false.

Please test and close if OK.

Alfred

2019-01-17 11:16

reporter   ~0113447

Working as expected.
Thanks a lot !

Issue History

Date Modified Username Field Change
2019-01-08 08:01 Alfred New Issue
2019-01-08 08:01 Alfred File Added: REV60026.diff
2019-01-08 08:02 Alfred Note Added: 0113257
2019-01-08 22:16 Maxim Ganetsky LazTarget => -
2019-01-08 22:16 Maxim Ganetsky Note Added: 0113275
2019-01-08 22:16 Maxim Ganetsky Assigned To => Maxim Ganetsky
2019-01-08 22:16 Maxim Ganetsky Status new => feedback
2019-01-09 07:41 Alfred Note Added: 0113279
2019-01-09 07:41 Alfred Status feedback => assigned
2019-01-09 09:20 wp Note Added: 0113282
2019-01-17 01:15 Maxim Ganetsky Fixed in Revision => 60097
2019-01-17 01:15 Maxim Ganetsky Note Added: 0113443
2019-01-17 01:15 Maxim Ganetsky Status assigned => resolved
2019-01-17 01:15 Maxim Ganetsky Fixed in Version => 2.2
2019-01-17 01:15 Maxim Ganetsky Resolution open => fixed
2019-01-17 11:16 Alfred Note Added: 0113447
2019-01-17 11:16 Alfred Status resolved => closed