gnugettext für FPC

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Antworten
wolf_z
Beiträge: 88
Registriert: Mo 31. Aug 2009, 09:31

gnugettext für FPC

Beitrag von wolf_z »

Hallo

Ich bin gerade dabei, ein Delphi-Programm nach Lazarus zu portieren, in welchem die Internationalisierung mit der unit "gnugettext" realisiert wurde. Jetzt finde ich im Internet zwar Versionen für Kylix, etc., aber nicht für Lazarus bzw. FPC. In FPC gibt es ja die unit "gettext", die die gleichen Sprachdateien ähnlich verarbeitet ('locale/.../de/irgendwas.mo'), aber meines Wissens nur Ressourcen-Strings auswertet, aber keine Funktionen wie z.B. _("Translate this sentence to german") zur Verfügung stellt. Die Unit "gnugettext" für Delphi ist wesentlich umfangreicher und komfortabler, als "gettext" für FPC.

Ich versuche gerade, gnugettext für Delphi einfach in Lazarus zu verwenden, aber ich scheitere an Funktionen wie z.B. "EnumResourceModules", die in Delphi in der Unit "System" definiert sind. In FPC bzw. Lazarus finde ich diese Funktion aber nicht.

Ich komme irgendwie nicht weiter. Deshalb hab ich folgende Fragen. Die Beantwortung einer einzigen könnte mir weiterhelfen :?

Gibt es für FPC ein Register, über das man die Existenz von so einer Funktion wie "EnumResourceModules" nachschlagen kann?
Gibt es eine Version von "gnugettext", die man direkt in FPC verwenden kann?
Gibt es irgendwelche Erweiterungen von "gettext", z.B. _('xy'), mit denen direkt aus der geladenen Sprachdatei heraus Ausdrücke im Quellcode übersetzen kann?

Gruß Wolfgang

Benutzeravatar
theo
Beiträge: 10869
Registriert: Mo 11. Sep 2006, 19:01

Re: gnugettext für FPC

Beitrag von theo »

http://wiki.lazarus.freepascal.org/Spec ... ext=Search" onclick="window.open(this.href);return false;

wolf_z
Beiträge: 88
Registriert: Mo 31. Aug 2009, 09:31

Re: gnugettext für FPC

Beitrag von wolf_z »

Danke! Ich hatte dort nach "gnugettext" gesucht und nicht nach "gettext" und da kam nix! :?

Ich hab den richtigen Download für Lazarus daraufhin hier gefunden:

http://sourceforge.net/projects/lazarus ... dxgettext/" onclick="window.open(this.href);return false;

Der Download enthält ein Beispielprojekt, das ich aber nicht ans Laufen kriege.

Erstmal musste ich oben noch die Unit "windows" einfügen. Dann hat sich der compiler aufgehängt an

"Identifier not found: ResourceStringTableCount"

Das Problem hat wohl noch jemand anders schon mal gehabt, aber darauf keine Antwort bekommen:

http://www.mail-archive.com/lazarus@laz ... 02033.html" onclick="window.open(this.href);return false;

Die Funktion ist also wohl in ObjPas enthalten, aber durch Compilerdirektiven ausgeklammert. Was muss ich einstellen, um die Funktion "ResourceStringTableCount" verwenden zu können, ohne woanders Probleme zu kriegen?

Benutzeravatar
theo
Beiträge: 10869
Registriert: Mo 11. Sep 2006, 19:01

Re: gnugettext für FPC

Beitrag von theo »

K.A. Frag doch diesen Olivier Guilbaud http://wiki.lazarus.freepascal.org/DxGetText" onclick="window.open(this.href);return false;

wolf_z
Beiträge: 88
Registriert: Mo 31. Aug 2009, 09:31

Re: gnugettext für FPC

Beitrag von wolf_z »

Den Olivier Guilbaud frag ich, wenn alle Stricke reißen. Vorerst vermute ich, liegt das Problem an irgendeiner Compiler-Einstellung. Also ich hab das Problem noch ein wenig weiter eingegrenzt.

Die nicht gefundenen Identifier "ResourceStringTableCount" bzw. "SetResourceStringValue", etc. gehören zu einer Gruppe aus "package 'rtl'", die hier gelistet sind:

http://lazarus-ccr.sourceforge.net/docs ... dex-8.html" onclick="window.open(this.href);return false;

Klicke ich dort auf "SetResourceStringValue", wird mir dieses schöne kleine Beispielprogramm angeboten:

Code: Alles auswählen

Program project1;
 
{ Program to demonstrate the SetResourceStringValue function. }
{$Mode Delphi}
 
ResourceString
 
  First  = 'First string';
  Second = 'Second String';
 
Var I,J : Longint;
    S : AnsiString;
 
begin
  { Print current values of all resourcestrings }
  For I:=0 to ResourceStringTableCount-1 do
    For J:=0 to ResourceStringCount(i)-1 do
      begin
      Writeln ('Translate => ',GetResourceStringDefaultValue(I,J));
      Write   ('->');
      Readln(S);
      SetResourceStringValue(I,J,S);
      end;
  Writeln ('Translated strings : ');
  For I:=0 to ResourceStringTableCount-1 do
    For J:=0 to ResourceStringCount(i)-1 do
      begin
      Writeln (GetResourceStringDefaultValue(I,J));
      Writeln ('Translates to : ');
      Writeln (GetResourceStringCurrentValue(I,J));
      end;
end.


Damit habe ich dann flugs selbst ein Projekt angelegt und die Compilierung hängt an der gleichen Stelle. Es muss aber doch möglich sein, solch ein Lazarus-Programm aus der Lazarus-Dokumentation mit Lazarus an's Laufen zu kriegen! Das kann doch nur eine Kompilereinstellung sein!

Dann hab ich die entsprechenden Befehle auch in der Unit "Translations" gefunden, allerdings in einen Compiler-Switch für FPC Vers. 2_0 eingeschlossen:

Code: Alles auswählen

Unit Translations
...
{$ifdef ver2_0}
      for TableID:=0 to ResourceStringTableCount - 1 do begin      
      .....
      end;
{$else ver2_0}
      SetUnitResourceStrings(ResUnitName,@Translate,po);
{$endif ver2_0}
So wie ich diesen Compiler-Switch verstehe, gelten in dieser Unit die Funktionen Resource-Strings betreffend nur für Vers 2.0.xy. Ich habe aber 2.2.2.

Aber da kann doch was nicht stimmen. Eine ganze Gruppe von Funktionen, die allgemein ohne Versionsbeschränkung in einer Referenz dokumentiert sind, aber dann in den Units, z.B. Translations, bzgl. ihrer Versionsgültigkeit auf 2.0 eingeschränkt sind.

Versteht das jemand?

Falls das tatsächlich der Fall sein sollte, müsste man in gnugettext nur die folgende Funktion umschreiben unter Verwendung von Funktionen wie " SetUnitResourceStrings(ResUnitName,@Translate,po);" (s. Beispiel oben), dann musste gnugettext eigentlich laufen:

Code: Alles auswählen

{$IFDEF FPC}
Unit gnugettext
...
procedure TranslateAllResourceStrings;
var I,J : Longint;
    S   : WideString;
begin
  {$ifdef DXGETTEXTDEBUG}
  DefaultInstance.DebugWriteln('TranslateAllResourceStrings (ResourceStringTableCount='+IntToStr(ResourceStringTableCount)+')');
  {$endif}
  for I:=0 to ResourceStringTableCount-1 do
  begin
    for J:=0 to ResourceStringCount(i)-1 do
    begin
      S:=DefaultInstance.gettext(GetResourceStringDefaultValue(I,J));
      SetResourceStringValue(I,J,S);
    end;
  end;
end;
 
{$ENDIF}
Würde natürlich erstmal viel Einarbeitung in die Resource-String-Verwaltung erfordern. Aber dann hätte man eine aktuelle brauchbare "gnugettext"

Vielleicht jemand da, der sich mit Resource-String-Verwaltung gut auskennt? :mrgreen:

Aber vielleicht liegt es ja auch nur an einer Compilereinstellung (s. Programm ganz oben). Ein Beispielprogramm in der aktuellen Lazarus-Dokumentation, das man nicht mit Copy and Paste an's Laufen kriegt? Das kann doch nicht sein :!:

wolf_z
Beiträge: 88
Registriert: Mo 31. Aug 2009, 09:31

Re: gnugettext für FPC

Beitrag von wolf_z »

Ich habe für mich das Problem jetzt so gelöst, dass ich keine Resource-Strings verwende. Alles andere geht mit "lazarus gnugettext" und das reicht mir.

Außer dem Ausklammern des Codes in "TranslateAllResourceStrings" muss man noch folgende Änderung in der Funktion "dgettext" von gnugettext vornehmen:

Code: Alles auswählen

function TGnuGettextInstance.dgettext(const szDomain: string;
  const szMsgId: widestring): widestring;
begin
  if not Enabled then begin
    {$ifdef DXGETTEXTDEBUG}
    DebugWriteln ('Translation has been disabled. Text is not being translated: '+szMsgid);
    {$endif}
    Result:=szMsgId;
  end else begin
    // changed/01.09.2009 Result:=UTF8Decode(LF2LineBreakA(getdomain(szDomain,DefaultDomainDirectory,CurLang).gettext(StripCR(utf8encode(szMsgId)))));   //  -> 'ß', 'ü', etc. -> the Result can't be displayed in showMessage and similar!
    Result:=getdomain(szDomain,DefaultDomainDirectory,CurLang).gettext(StripCR(utf8encode(szMsgId)));
    {$ifdef DXGETTEXTDEBUG}
    if (szMsgId<>'') and (Result='') then
      DebugWriteln (Format('Error: Translation of %s was an empty string. This may never occur.',[szMsgId]));
    {$endif}
  end;
end;
Danke also für die Hinweise. "lazarus gnugettext" ist ja nicht so leicht zu finden. Langfristig müsste sich aber wohl mal jemand um die Aktualisierung kümmern. Ich schicke dem Olivier Guilbaud mal 'ne Mail (nächsten Sonntag :mrgreen:)

Aber wenn jemand anderes (auch später) eine Lösung für das Problem findet, wäre ich für einen Hinweis an dieser Stelle dankbar.

Antworten