Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus / 2008-03

TPOFile.Translate always fails on the Identifier lookup

4 messages · 2 people ·

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Graeme Geldenhuys

Hi,

I'm using LCL's translations.pas unit in fpGUI. I have simply removed the LCL specific units from the uses clause and replaced it with FPC or fpGUI ones. The actual processing of the POFiles are identical, nothing has changed. I have two queries though....

1) Why doesn't the translations.pas unit use FPC's standard TFPObjectHashTable class, but instead opt for a custom written TStringHashList (StringHashList.pas unit)? What is the benefit of using the StringHashList unit?

2) In the code below (TPOFile.Translate), the first lookup using FIdentifierToItem.Data[] always returns nil. It seems that the lookup via the Identifier (eg: gfx_constants.rsLanguage) always fails. Has anybody else noticed this in the LCL as well?

The reason I detected it, is because fpGUI can change it's default compiled language. It uses include files to pull in the correct translation based on a $DEFINE statement. This code is show below...

------------ COPY ---------------
{ Define Compiler language symbol (eg: de for German) to include the correct language resource file otherwise the Default (English) resource file will be used. }

{.$DEFINE de} // German
{.$DEFINE ru} // Russian
{.$DEFINE fr} // French
{.$DEFINE pt} // Portuguese (Brazil)
{.$DEFINE za} // Afrikaans
{.$DEFINE it} // Italian

{$IF defined(de)}
  {$I lang_german.inc}
{$ELSEIF defined(ru)}
  {$I lang_russian.inc}
{$ELSEIF defined(fr)}
  {$I lang_french.inc}
{$ELSEIF defined(pt)}
  {$I lang_portuguese.inc}
{$ELSEIF defined(za)}
  {$I lang_afrikaans.inc}
{$ELSEIF defined(it)}
  {$I lang_italian.inc}
{$ELSE}
  {$I lang_english.inc}
{$IFEND}
-------------- END ---------------

The standard (runtime loaded) translation files (*.po) was created from the original English include file. Now if I change fpGUI's default language to say Russian, the only way to do a successful PO lookup is via the resourcestring identifier (eg:
gfx_constants.rsLanguage), because the original string in the PO files are based on the English language.

Anybody got any clues as to why the FIdentifierToItem.Data[] always returns nil? I even replaced the the internal hash class from TStringListHash to FPC's TFPObjectHashTable, but the problem still persists!

----------------------- COPY -------------------------
function TPOFile.Translate(const Identifier, OriginalValue: String): String;
var
  Item: TPOFileItem;
begin
  Item:=TPOFileItem(FIdentifierToItem.Data[Identifier]);
  if Item=nil then
    Item:=TPOFileItem(FOriginalToItem.Data[OriginalValue]);
  if Itemnil then begin
    Result:=Item.Translation;
    if Result='' then RaiseGDBException('TPOFile.Translate Inconsistency');
  end else
    Result:=OriginalValue;
end;
----------------------- END -------------------------

If the problem is still not clear, I can try and create a small demo project doing exactly what fpGUI does, which will highlight the issue.

By the way, I'm trying all this under Linux and changing the LANG environment variable.

Regards,
- Graeme -

_______________________________________________
fpGUI - a cross-platform Free Pascal GUI toolkit
http://opensoft.homeip.net/fpgui/

Reply by email

Mattias Gaertner
to Graeme Geldenhuys
Show quoted text 10 lines
Hi, I'm using LCL's translations.pas unit in fpGUI. I have simply removed the LCL specific units from the uses clause and replaced it with FPC or fpGUI ones. The actual processing of the POFiles are identical, nothing has changed. I have two queries though.... 1) Why doesn't the translations.pas unit use FPC's standard TFPObjectHashTable class, but instead opt for a custom written TStringHashList (StringHashList.pas unit)?

AFAIR TStringHashList existed first.

What is the benefit of using the StringHashList unit?

AFAIK TStringHashList is faster.

2) In the code below (TPOFile.Translate), the first lookup using FIdentifierToItem.Data[] always returns nil. It seems that the lookup via the Identifier (eg: gfx_constants.rsLanguage) always fails. Has anybody else noticed this in the LCL as well?

Maybe the russian .po file is buggy?
Uncomment the debugln in TPOFile.Add and see what is added.

Show quoted text 33 lines
[...] The standard (runtime loaded) translation files (*.po) was created from the original English include file. Now if I change fpGUI's default language to say Russian, the only way to do a successful PO lookup is via the resourcestring identifier (eg: gfx_constants.rsLanguage), because the original string in the PO files are based on the English language. Anybody got any clues as to why the FIdentifierToItem.Data[] always returns nil? I even replaced the the internal hash class from TStringListHash to FPC's TFPObjectHashTable, but the problem still persists! ----------------------- COPY ------------------------- function TPOFile.Translate(const Identifier, OriginalValue: String): String; var Item: TPOFileItem; begin Item:=TPOFileItem(FIdentifierToItem.Data[Identifier]); if Item=nil then Item:=TPOFileItem(FOriginalToItem.Data[OriginalValue]); if Itemnil then begin Result:=Item.Translation; if Result='' then RaiseGDBException('TPOFile.Translate Inconsistency'); end else Result:=OriginalValue; end; ----------------------- END ------------------------- If the problem is still not clear, I can try and create a small demo project doing exactly what fpGUI does, which will highlight the issue.

That will help.

Mattias

Reply by email

Graeme Geldenhuys
to Graeme Geldenhuys: I'm using LCL's translations.pas unit in fpGUI. I have simply removed the LCL specific…
Graeme Geldenhuys wrote 5 lines
2) In the code below (TPOFile.Translate), the first lookup using FIdentifierToItem.Data[] always returns nil. It seems that the lookup via the Identifier (eg: gfx_constants.rsLanguage) always fails. Has anybody else noticed this in the LCL as well?

OK, I found the bug..... The character between the unitname and the resourcestring identifier is different. Here is some debug output showing the issue...

In TPOFile.Add() the Identifier has a ':' delimiter....

TPOFile.Add: gfx_constants:rslanguage | English | Afrikaans TPOFile.Add: gfx_constants:rsok | OK | Goed
TPOFile.Add: gfx_constants:rscancel | Cancel | Kanselleer

Then in TPOFile.Translate() the identifer has a '.' delimiter. No wonder the hash lookup never succeeds!

TPOFile.Translate: gfx_constants.rslanguage | English identifier failed, trying original value
TPOFile.Translate: gfx_constants.rsok | OK
identifier failed, trying original value

Attached is a patch that fixes this problem in translations.pas unit. In TPOFile.Translate() I simply replace the first '.' with a ':' character. The Identifier lookup now succeeds.
The resourcestring identifier from the *.rst files get modified by 'rstconv' program when you generate *.po files. I'm not really sure which one ,
- Graeme -

_______________________________________________
fpGUI - a cross-platform Free Pascal GUI toolkit
http://opensoft.homeip.net/fpgui/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: translations.diff
Type: text/x-patch
Size: 627 bytes
Desc: not available
Url : http://www.lazarus.freepascal.org/pipermail/lazarus/attachments/20080301/bf356eaa/attachment.bin

Reply by email

Graeme Geldenhuys
to Mattias Gaertner: On Sat, 1 Mar 2008 20:08:04 +0200 AFAIR TStringHashList existed first. AFAIK…
Mattias Gaertner wrote 5 lines
> 1) Why doesn't the translations.pas unit use FPC's standard > TFPObjectHashTable class, but instead opt for a custom written > TStringHashList (StringHashList.pas unit)? AFAIR TStringHashList existed first.

OK, that would make sense.

> What is the benefit of > using the StringHashList unit? AFAIK TStringHashList is faster.

One needs to changes about 4 lines of code to switch between the two hash implementations. Any idea how I can test the speed difference between the two?

Regards,
- Graeme -

_______________________________________________
fpGUI - a cross-platform Free Pascal GUI toolkit
http://opensoft.homeip.net/fpgui/

Reply by email