Recent

Author Topic: .PO file location / Portable Applications  (Read 9859 times)

TheBlackSheep

  • Jr. Member
  • **
  • Posts: 93
.PO file location / Portable Applications
« on: August 01, 2011, 09:42:40 pm »
I sort of asked this question in the miscellaneous area  but didn't get a reply (might have written the q. badly to be honest) so thought I'd re-ask in the translations section to see if anyone here has had experience of this...

As I understand it, the specification for Portable Application Format files (here);

http://portableapps.com/development/portableapps.com_format

suggests putting any application specific data in a sub-folder called "data" and/or anything else (help and possibly '.po' translation files) in a sub-folder called "other" and leaving the main installation folder with basically just the application itself.

For language translations default the "DefaultTranslator" unit doesn't look in these folders so to comply with the specification I'd have to change the unit to look elsewhere (unless there's an override somewhere I haven't seen yet). 

The format for the "installer.ini" suggests that the PAF supports multiple languages but not how this is achieved (I'm presuming this would be development environment specific but as far as developing in Lazarus we have the potential to make this relatively easy).

I just wondered if anyone has had experience of writing applications that meet this particular specfication and had any thoughts/recommendations for how they are implementing it?

TheBlackSheep

lainz

  • Guest
Re: .PO file location / Portable Applications
« Reply #1 on: August 02, 2011, 01:51:55 am »
Use resourcestrings instead automatic translation.

You can set the .po files directory in the Project Options.

Put this code in the .lpr file:

procedure TranslateLCL;
var
  Lang, FallbackLang: String;
begin
  Lang:='';
  FallbackLang:='';
  LCLGetLanguageIDs(Lang,FallbackLang);
  TranslateUnitResourceStrings('main','data/language.%s.po',Lang,FallbackLang);
end;

begin
  TranslateLCL;
...

TheBlackSheep

  • Jr. Member
  • **
  • Posts: 93
Re: .PO file location / Portable Applications
« Reply #2 on: August 02, 2011, 12:46:09 pm »

Hi Lainz,

thanks for the help but can't seem to get it to work (or at least not sure how I test it if it is working as I'm just seeing the default english values);

I've got two PO files (default Eng with only a ".po" extension and a German one with a ".de.po" file suffix) in the subfolder "other/languages" - the PO file setup function below is just a generic way of passing the path and filename of the file to be loaded (I'd hope to use the same code frequently for other applications and I'd just have to copy function this without any further amendments).

Code: [Select]
..., Translations, LCLProc;

{$R *.res}

  procedure TranslateLCL;
  var
    PODirectory, POFile, Lang, FallbackLang: String;
  begin
    PODirectory := 'other/languages/';
    POFile := PODirectory+ChangeFileExt(ExtractFileName(Application.ExeName),'.')+'%s.po';
    Lang:='de';
    FallbackLang:='';
   // LCLGetLanguageIDs(Lang,FallbackLang);
    Translations.TranslateUnitResourceStrings('EngLangRes', POFile, Lang, FallbackLang);
  end;   

begin
  TranslateLCL;
...

"EngLasRes.pas" is a unit with all the resource strings in it.

I assumed if I change the Lang variable to "de" as per the above this is how I could test it but I still get English resources displayed.

Conversely by changing the DefaultTranslator.pas to accept the other\languages sub-folder and setting the params in the runtime to "--lang de" (and therefore not requiring the above) it appears to work fine - so not sure why the above doesn't seem to work. 

The Black Sheep

lainz

  • Guest
Re: .PO file location / Portable Applications
« Reply #3 on: August 02, 2011, 07:11:58 pm »
It's strange doesn't works.

Bart

  • Hero Member
  • *****
  • Posts: 5290
    • Bart en Mariska's Webstek
Re: .PO file location / Portable Applications
« Reply #4 on: August 03, 2011, 11:18:58 am »
You may also consider including the po-files as (Lazarus-) resources inside your program.

Create the resource like:

Code: [Select]
lazres mystrings.lrs my-po-file.po

Then inside Lazarus include them like

Code: [Select]
  {$I mystrings.lrs}

This also resolves the possible problems of locating where youre executable is.
(Which is not 100% reliable on *nix)

There is some wiki article about this, but the example crashed with my Lazarus.
I have some working code, and a somewhat stripped version of translations.pas, which (provided the po-file is in utf-8 encoding) results in your executable being 1Mb smaller (if size matters to you).

Bart

lainz

  • Guest
Re: .PO file location / Portable Applications
« Reply #5 on: August 03, 2011, 11:52:41 pm »
You're using Windows? The problem is the path!

Use 'other\languages\' instead 'other/languages/'

See the attached project.

TheBlackSheep

  • Jr. Member
  • **
  • Posts: 93
Re: .PO file location / Portable Applications
« Reply #6 on: August 12, 2011, 04:30:44 pm »

Hi Lainz

thanks for the demo - it turned out it wasn't the path that was incorrect. Your demo application did nevertheless indicate what was wrong with my project. 

The DefaultTranslator method automatically translated the captions of things like buttons and menu items whereas with the other method you have to set them all manually in a resource file.  The application I've been developing is a WinXP toolbar icon one and so the menu's, labels, buttons and forms etc. I was seeing weren't being changed in the TranslateLCL method but were being changed when using the DefaultTranslator unit instead (I just hadn't noticed this).  The TranslateLCL was working fine for things like messagedlg's - basically all the entries in the resourcestring unit  - but I hadn't used the application to a point where these were visible.

I suppose it might make sense to modify the DefaultTranslator to have an optional path rather than the pre-defined one's it has currently or I go through all the forms, menu's, labels and buttons and set these up in the resourcestring unit as well and define them in the create event of the form. 

Are there advantages of doing translations via the "official" method of TranslateLCL over the "unofficial" DefaultTranslator method?

TheBlackSheep

 

TinyPortal © 2005-2018