Buttons in MessageBox deutsch beschriften? Wie?

Für Fragen rund um die Ide und zum Debugger
Mattias
Lazarusforum e. V.
Beiträge: 175
Registriert: Do 22. Mai 2008, 15:14
OS, Lazarus, FPC: LinuxOSX (L head FPC head)
CPU-Target: xxBit

Re: Buttons in MessageBox deutsch beschriften? Wie?

Beitrag von Mattias »

Socke hat geschrieben:Werden .po-Files, die als Ressource eingebunden sind, automatisch (mit DefaultTranslator) verwendet?


Nein. So eine Funktion ist willkommen.

Socke
Lazarusforum e. V.
Beiträge: 3158
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: Buttons in MessageBox deutsch beschriften? Wie?

Beitrag von Socke »

Mattias hat geschrieben:Nein. So eine Funktion ist willkommen.

Ich habe da noch einige Verständnisfrage:
Die LCL sammelt in der Unit LCLStrConsts alle Ressoucen-Strings; für diese Unit gibt es entsprechende .po-Dateien.
Wenn ich für ein Projekt in den Projekteinstellung i18n einschalte, wird nur eine .po-Datei für die gesamte Anwendung erstellt. Warum sind die Ressoucen-Strings aus LCLStrConsts hier nicht enthalten? Wie wird bestimmt, welche Ressoucen-Strings in welcher .po-Datei geschrieben werden? Wie sieht das bei (mehreren) Packages aus? Was ist mit der Übersetzung der RTL (RTLConsts) - wo liegen die .po-Dateien hierzu?

Was die Funktion angeht, ein erster Entwurf (Verwende wer will ;-) Bild)

Code: Alles auswählen

(* Changes:
 *  1 - Initial Version with po files
 *  2 - Also accept mo files with gettext and set LRSTranslator
*)

uses
  Translations, resource, lazutf8, LResources, LCLTranslator, gettext;
 
(* Create and assing a translator for form resouces from a po resource
 * Requires patch from http://bugs.freepascal.org/view.php?id=27616
 *)

procedure SetLRSTranslatorFromResouce(const aResName: String; aModule: TFPResourceHMODULE;
  aResouceType: PChar);
var
  rs: TResourceStream;
  po: TPOFile;
  Trls: TUpdateTranslator;
  mo: TMOFile;
begin
  rs := TResourceStream.Create(aModule, aResName, aResouceType);
  try
    if UpperCase(RightStr(aResName, 2)) = 'PO' then
    begin
      po := TPOFile.Create(rs, False);
      Trls := TPOTranslator.Create(po);
    end else
    begin
      mo := TMOFile.Create(rs);
      Trls := TDefaultTranslator.Create(mo);
    end;
    LRSTranslator.Free;
    LRSTranslator := Trls;
  finally
    rs.Destroy;
  end;
end;
 
(* Generic/Minimal translation from resouce streams with maximum parameters
 *)

procedure TranslateUnitFromResource(const aUnit, aResouceName: String;
  aInstance: TFPResourceHMODULE; aResouceType: PChar);
var
  po: TPOFile;
  rs: TResourceStream;
  mo: TMOFile;
begin
  po := nil;
  mo := nil;
 
  rs := TResourceStream.Create(aInstance, aResouceName, aResouceType);
  try
    if UpperCase(RightStr(aResouceName, 2)) = 'PO' then
    begin
      po := TPOFile.Create(rs, False);
      Translations.TranslateUnitResourceStrings(aUnit, po);
    end else
    begin
      mo := TMOFile.Create(rs);
      gettext.TranslateUnitResourceStrings(aUnit, mo);
    end;
  finally
    po.Free;
    mo.Free;
    rs.Destroy;
  end;
end;
 
(* Enumerates all RT_RCDATA resouces to a TStringList
 *)

function EnumPoResources({%H-}ModuleHandle : TFPResourceHMODULE; ResourceType, ResourceName : PChar; lParam : PtrInt) : LongBool; stdcall;
var
  l: TStringList;
  ftype: String;
begin
  Assert(ResourceType = PChar(RT_RCDATA), Format('Invalid resouce type, got %d expected %d.', [PtrInt(ResourceType), RT_RCDATA]));
  Assert(lParam <> 0, 'String list not assigned.');
  l := TStringList(lParam);
  Assert(l is TStrings, Format('Got list class %s expected descendant of %s.', [l.ClassName, TStrings.ClassName]));
  ftype := upcase(RightStr(String(ResourceName), 2));
  if (ftype = 'PO') or (ftype = 'MO') then
    l.Add(ResourceName);
  Result := True;
end;
 
(* Expects resouce name format: <UNIT>.<LANGUAGE>.PO
 * with <UNIT>     = Unit name
 *      <LANGUAGE> = language code ('de_DE' or 'de')
 * resouce name is used case insensitive
 *
 * thus a resouce name is at least 7 characters long
 *)

procedure TranslateAllUnitsFromResource;
var
  ResourceNames: TStringList;
  ResName: String;
  LangDelim: SizeInt;
  Lang: String;
  T: String;
  PoUnitName: String;
  PoLangCode: String;
  PoLangCodeLen: Integer;
  appname: String;
begin
  // only one way to get a language ID, for full comatibiltiy,
  // LCLTranslator.FindLocaleFileName() should be split up
  Lang := '';
  T := '';
  LazGetLanguageIDs(Lang, T);
  Lang := UpperCase(Lang)// case insensitive
  T := UpperCase(T);        // case insensitive
  appname := ExtractFileNameOnly(Paramstr(0));
  appname := Uppercase(appname);
 
  ResourceNames := TStringList.Create;
  try
    EnumResourceNames(HINSTANCE, PChar(RT_RCDATA), @EnumPoResources, PtrInt(ResourceNames));
    for ResName in ResourceNames do
    begin
      if Length(ResName) < 7 then
        Continue;
      ResName := UpperCase(ResName)// case insensitive
 
      Assert(
        (RightStr(ResName, 2) = 'PO') or
        (RightStr(ResName, 2) = 'MO'),
        'Unexpected resouce name.'
      );
 
      LangDelim := Pos('.', ResName);
      PoUnitName := Copy(ResName, 1, LangDelim - 1);
      Assert(Length(PoUnitName) >= 1, 'Empty unit name.');
 
      PoLangCodeLen := Length(ResName) - LangDelim - Length('.PO');
      PoLangCode := Copy(ResName, LangDelim+1, PoLangCodeLen);
      if Length(PoLangCode) = 0 then
        continue; // No language code found
 
      if (PoLangCode = Lang) or (PoLangCode = T) then
      begin
        // always translate the "Unit". it may also be the project file (.lpr)
        TranslateUnitFromResource(PoUnitName, ResName, HINSTANCE, PChar(RT_RCDATA));
        // Translator for form resources
        if PoUnitName = appname then
          SetLRSTranslatorFromResouce(ResName, HInstance, Pchar(RT_RCDATA));
      end;
 
    end;
  finally
    ResourceNames.Destroy;
  end;
end;
Zuletzt geändert von Socke am Fr 6. Mär 2015, 19:40, insgesamt 1-mal geändert.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

Mattias
Lazarusforum e. V.
Beiträge: 175
Registriert: Do 22. Mai 2008, 15:14
OS, Lazarus, FPC: LinuxOSX (L head FPC head)
CPU-Target: xxBit

Re: Buttons in MessageBox deutsch beschriften? Wie?

Beitrag von Mattias »

Mattias hat geschrieben:Nein. So eine Funktion ist willkommen.


Zum Beispiel so:
http://wiki.lazarus.freepascal.org/Tran ... executable

Socke hat geschrieben:Die LCL sammelt in der Unit LCLStrConsts alle Ressoucen-Strings; für diese Unit gibt es entsprechende .po-Dateien.
Wenn ich für ein Projekt in den Projekteinstellung i18n einschalte, wird nur eine .po-Datei für die gesamte Anwendung erstellt. Warum sind die Ressoucen-Strings aus LCLStrConsts hier nicht enthalten?


Jeder Resourcestring ist in genau einer .po Datei. Jeder Übersetzer muss also jeden string nur einmal bearbeiten.

Socke hat geschrieben:Wie wird bestimmt, welche Ressoucen-Strings in welcher .po-Datei geschrieben werden? Wie sieht das bei (mehreren) Packages aus?


Die IDE erzeugt eine .po Datei pro Projekt und pro Package.

Socke hat geschrieben:Was ist mit der Übersetzung der RTL (RTLConsts) - wo liegen die .po-Dateien hierzu?


Keine Ahnung.

Socke
Lazarusforum e. V.
Beiträge: 3158
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: Buttons in MessageBox deutsch beschriften? Wie?

Beitrag von Socke »

Mattias hat geschrieben:
Mattias hat geschrieben:Nein. So eine Funktion ist willkommen.


Zum Beispiel so:
http://wiki.lazarus.freepascal.org/Tran ... executable

In meinem Code gehe ich von den FPC-Ressoucen aus (nicht LRS). Diese kann man ja mittlerweile bequem über die Projektoptionen hinzufügen.

Mattias hat geschrieben:Die IDE erzeugt eine .po Datei pro Projekt und pro Package.

Danke für den Hinweis. Zu diesem Thema gibt es im Wiki recht wenig Informationen. Ist das so gewollt, weil - z.B. - gettext sowieso auf String-Ebene arbeitet und damit die Unit der Ressouce-Strings für die Übersetzung nicht releavant ist? Ich könnte mir auch vorstellen, dass pro Unit eine .po-Datei gewünscht wird - diesen Weg müsste man derzeit ohne die IDE beschreiten.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

Mattias
Lazarusforum e. V.
Beiträge: 175
Registriert: Do 22. Mai 2008, 15:14
OS, Lazarus, FPC: LinuxOSX (L head FPC head)
CPU-Target: xxBit

Re: Buttons in MessageBox deutsch beschriften? Wie?

Beitrag von Mattias »

Socke hat geschrieben:Ich könnte mir auch vorstellen, dass pro Unit eine .po-Datei gewünscht wird - diesen Weg müsste man derzeit ohne die IDE beschreiten.


Das könnte man ja optional machen. Patches sind willkommen.

Socke
Lazarusforum e. V.
Beiträge: 3158
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: Buttons in MessageBox deutsch beschriften? Wie?

Beitrag von Socke »

Mattias hat geschrieben:
Socke hat geschrieben:Ich könnte mir auch vorstellen, dass pro Unit eine .po-Datei gewünscht wird - diesen Weg müsste man derzeit ohne die IDE beschreiten.


Das könnte man ja optional machen. Patches sind willkommen.


Mein aktueller Ansatz wäre:
  • Eine Datei für alle Formulare. Dateiname wäre <projekt>.po (<projekt> Dateiname ohne Erweiterung der Anwendung). Diese .po-Datei werden über einen TPOTranslator an LResoucres.LRSTranslator zugewiesen um die Formulare zu übersetzen. Damit das geht, muss dieser Patch http://bugs.freepascal.org/view.php?id=27616 eingebaut werden.
  • Für jede Unit mit Ressourcen-Strings wird eine .po-Datei erstellt
Wie setzt man denn die Ressoucen-Strings der Projektdatei? Über TranslateUnitResourceStrings() funkioniert das bei mir nicht - mein Test-Ressoucen-String bleibt unübersetzt. Man könnte TranslateResourceStrings() verwenden, womit dann aber auch die Ressourcen-Strings aus den Units übersetzt werden. Das wäre aus meiner Sicht bei mehreren .po-Dateien nicht erwünscht.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

ruewa
Beiträge: 153
Registriert: Sa 12. Apr 2014, 14:43

Re: Buttons in MessageBox deutsch beschriften? Wie?

Beitrag von ruewa »

Ich hatte zu dem Thema hier mal was zusammengestellt: http://www.lazarusforum.de/viewtopic.php?p=69170#p69170

Dort enthalten ist auch eine Unit, die das Ganze weitgehend automatisiert. Leider versickert sowas hier allzu lautlos, ich selber tu mich ja schon schwer, es wiederzufinden...

Vielleicht hilft das weiter?

Gruß Rüdiger

Socke
Lazarusforum e. V.
Beiträge: 3158
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: Buttons in MessageBox deutsch beschriften? Wie?

Beitrag von Socke »

ruewa hat geschrieben:Dort enthalten ist auch eine Unit, die das Ganze weitgehend automatisiert.

Dan haben wir ja jetzt alles zusammen (Datei, alte Lazarus-Ressourcen und neue FPC-Ressourcen) ;-)

ruewa hat geschrieben:Leider versickert sowas hier allzu lautlos, ich selber tu mich ja schon schwer, es wiederzufinden...

Ich hatte nie verstanden, warum hier im Forum eine eigene WissensDB aufgebaut werden soll, wenn doch schon recht viel im Wiki vorhanden ist. Allgemein gesehen ist das Wiki aktueller - bei den Übersetzungen ist der Unterschied aber nicht so groß.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

ruewa
Beiträge: 153
Registriert: Sa 12. Apr 2014, 14:43

Re: Buttons in MessageBox deutsch beschriften? Wie?

Beitrag von ruewa »

Socke hat geschrieben:Ich hatte nie verstanden, warum hier im Forum eine eigene WissensDB aufgebaut werden soll, wenn doch schon recht viel im Wiki vorhanden ist.


Doch, das könnte m.E. schon sinnvoll sein. Denn ein solcher Text, der ja halb in Richtung Tutorial, halb in Richtung Erklärung / technische Diskussion geht, paßt eher schlecht in die strammer gefaßte Wiki. Aber ich denke, beide Darstellungsarten haben ihre Berechtigung und sicherlich auch gegeneinander verschobene Adressatenkreise.

Man müßte es halt pflegen, d.h. dem Ganzen eine Struktur geben, die die Dinge dann auch auffindbar macht. Wenn ein Text am Ende in einem Thread, dessen Name nicht einmal erahnen läßt, was er enthält, mitten zwischen Diskussionsbeiträgen hängenbleibt, war's halt einfach nur für die Katz. Dafür steckt dann aber zuviel Arbeit drin. Sowas macht man also genau einmal...

Gruß Rüdiger

Antworten