[gelöst] i18n für eine Form in einem Package
[gelöst] i18n für eine Form in einem Package
Hallo Lazarusgemeinde
Ich habe leider noch nie die i18n benutzt und habe da so meine Sorgen damit.
Ich habe jede menge dazu gelesen, Google benutzt und hier aus dem Forum auch fast jeden Beitrag dazu gelesen.
Das "aktivieren" der i18n ist nicht so schwer, das habe ich soweit hinbekommen.
Das Beispiel "translation" aus den examples hat mir dabei gut geholfen.
Jedoch scheint die i18n bei einem Package ein wenig anders zu sein als für ein Projekt.
In einem Projekt kann ich bei i18n auch Captions von Komponenten ausschliessen, dazu gibt es in den Einstellungen ein Memo wo man das eintragen kann.
So eine Eingabemaske ist bei den Einstellungen bei i18n für ein Package nicht vorhanden,
Ich habe in einem Package eine Form und wollte da halt auch die i18n anwenden.
Ich habe dazu die "localizedforms.*"-Dateien zum Package hinzugefügt, die Form von "TLocalizedForm" abgeleitet und in der Form.lfm das erste wort durch "inherited" ersetzt.
Dann gibt es auch noch ResourceStrings welche ich in eine eigene Unit geschrieben habe.
Beim kompilieren des Packages wird auch eine po.Datei erstellt, allerdings nur mit den ResourceStrings.
Jedoch enthält die po.Datei keine Komponent Captionstrings, wie zum beispiel von einem Label oder Button.
Wenn ich ein Projekt erstelle und mein Package einbinde und dann für das Projekt ebenfalls i18n aktiviere -> und auch dort die "localizedforms.*"-Dateien zum Projekt hinzufüge und kompiliere, dann erhalte ich eine Warnung das die "localizedforms.*"-Dateien nun Duplicated sind.
Auf jedenfall steht dann in der Projekt.po Datei, Captions von Komponenten drin die auf der Haupt-Form sind. Ich hatte gehofft das dann auch die Komponent-Captions von der Form aus dem Pacckage enthalten sind, dem ist aber nicht so.
Wie muss ich das angehen?
Ich habe leider noch nie die i18n benutzt und habe da so meine Sorgen damit.
Ich habe jede menge dazu gelesen, Google benutzt und hier aus dem Forum auch fast jeden Beitrag dazu gelesen.
Das "aktivieren" der i18n ist nicht so schwer, das habe ich soweit hinbekommen.
Das Beispiel "translation" aus den examples hat mir dabei gut geholfen.
Jedoch scheint die i18n bei einem Package ein wenig anders zu sein als für ein Projekt.
In einem Projekt kann ich bei i18n auch Captions von Komponenten ausschliessen, dazu gibt es in den Einstellungen ein Memo wo man das eintragen kann.
So eine Eingabemaske ist bei den Einstellungen bei i18n für ein Package nicht vorhanden,
Ich habe in einem Package eine Form und wollte da halt auch die i18n anwenden.
Ich habe dazu die "localizedforms.*"-Dateien zum Package hinzugefügt, die Form von "TLocalizedForm" abgeleitet und in der Form.lfm das erste wort durch "inherited" ersetzt.
Dann gibt es auch noch ResourceStrings welche ich in eine eigene Unit geschrieben habe.
Beim kompilieren des Packages wird auch eine po.Datei erstellt, allerdings nur mit den ResourceStrings.
Jedoch enthält die po.Datei keine Komponent Captionstrings, wie zum beispiel von einem Label oder Button.
Wenn ich ein Projekt erstelle und mein Package einbinde und dann für das Projekt ebenfalls i18n aktiviere -> und auch dort die "localizedforms.*"-Dateien zum Projekt hinzufüge und kompiliere, dann erhalte ich eine Warnung das die "localizedforms.*"-Dateien nun Duplicated sind.
Auf jedenfall steht dann in der Projekt.po Datei, Captions von Komponenten drin die auf der Haupt-Form sind. Ich hatte gehofft das dann auch die Komponent-Captions von der Form aus dem Pacckage enthalten sind, dem ist aber nicht so.
Wie muss ich das angehen?
Zuletzt geändert von hubblec4 am Di 19. Okt 2021, 02:13, insgesamt 1-mal geändert.
Re: i18n für eine Form in einem Package
Ich bin nicht sicher, aber ich meine, das Übersetzungssystem tut sich mit der Vererbung vom Formularen schwer... Wahrscheinlich ist es besser, alles, auch die verwendeten Captions, als ResourceStrings zu definieren und zur Laufzeit zuzuweisen, genauso wie es die IDE auch macht.
Im Nachhinein weiß ich auch nicht, ob es eine gute Idee war, in dem Beispielprogramm die Übersetzungsroutinen in ein Formular zu packen, das immer weitervererbt wird. Im englischen Forum hat jemand daraus eine Komponente gemacht, was mir eigentlich besser gefällt: https://forum.lazarus.freepascal.org/in ... #msg156262. Vielleicht sollte ich mir das bei Gelegenheit genauer ansehen...
Im Nachhinein weiß ich auch nicht, ob es eine gute Idee war, in dem Beispielprogramm die Übersetzungsroutinen in ein Formular zu packen, das immer weitervererbt wird. Im englischen Forum hat jemand daraus eine Komponente gemacht, was mir eigentlich besser gefällt: https://forum.lazarus.freepascal.org/in ... #msg156262. Vielleicht sollte ich mir das bei Gelegenheit genauer ansehen...
Re: i18n für eine Form in einem Package
OK. Hatte da auch schon drüber nachgedacht alles als Resourcestring zu machen.wp_xyz hat geschrieben: Di 28. Sep 2021, 15:34 Ich bin nicht sicher, aber ich meine, das Übersetzungssystem tut sich mit der Vererbung vom Formularen schwer... Wahrscheinlich ist es besser, alles, auch die Formular-Captions, als ResourceStrings zu definieren und zur Laufzeit zuzuweisen, genauso wie es die IDE auch macht.
Und ich könnte dan in der UpdateTranslation methode die Captions manuell zu weisen.
Würde etwas mehr Code und Aufwand bedeuten, aber denke dann sollte es auch klappen.
Und sehe ich das richtig das ich dann die Form nicht zwingend von TLocalizedform ableiten muss?
Ebenso müsste ich dann auch nicht die localizedforms.*"-Dateien ins Package einbinden.
Dadurch sollte es dann auch keine Warnung im Projekt geben wegen doppelten Dateien?!
Diese Seite habe ich auch schon gelesen aber habe mir die Komponente noch nicht angeschaut.wp_xyz hat geschrieben: Di 28. Sep 2021, 15:34 Im Nachhinein weiß ich auch nicht, ob es eine gute Idee war, in dem Beispielprogramm die Übersetzungsroutinen in ein Formular zu packen, das immer weitervererbt wird. Im englischen Forum hat jemand daraus eine Komponente gemacht, was mir eigentlich besser gefällt: https://forum.lazarus.freepascal.org/in ... #msg156262. Vielleicht sollte ich mir das bei Gelegenheit genauer ansehen...
Müsste ich dann wohl auch mal tun, um zu schauen ob ich es in einem Package und und einem Projekt nutzen kann.
Re: i18n für eine Form in einem Package
Eigentlich brauchst du LocalizedForms gar nicht. Im Prinzip müssen die Forms in deinem Package eine öffentliche Methode haben, bei deren Aufruf sie sich neu übersetzen (z.B. Translate). Das Problem ist nur wie das Hauptformular bewirken kann, dass diese Methode aufgerufen wird. Leider bietet die LCL dafür keinen eingebauten Mechanismus.
Am einfachsten ist es, wenn du Formulare nur modal erzeugst. Dann ist es ausgeschlossen, dass während der Zeit, in der ein Formular aktiv ist, die Sprache geändert wird. Du musst also nur im OnCreate deiner Package-Formulare prüfen, was die aktuelle Sprache ist, und das Formular entsprechend übersetzen.
Bei nicht-modalen Formularen ist es komplizierter, und ich habe keine passende Methode parat, die mir gefällt. Du könntest natürlich, wenn die Sprache geändert worden ist, alle aktiven Formulare der Anwendung durchlaufen, ihren Typ prüfen und wenn es sich um ein Formular deines Packages handelt, nach einem Type-cast die nun bekannte Methode Translate aufrufen. Ist halt etwas sehr unförmig...
Eleganter wäre, an alle Formulare der Anwendung eine Nachricht zu schicken, die die Neuübersetzung anstößt. Aber da das keine Standard-Message ist, können Formulare aus anderen Packages damit nichts anfangen, selbst wenn sie mehrsprachen-fähig sind.
Oder du gehst den einfachen Weg, so wie die IDE: Du forderst nach einem Sprachenwechsel, dass die Anwendung neu gestartet werden muss. Jedes mehrsprachige Formular sollte in der Lage sein, bei einem erneuten Create die aktuelle Sprache abzufragen und sich entsprechend einzustellen.
Am einfachsten ist es, wenn du Formulare nur modal erzeugst. Dann ist es ausgeschlossen, dass während der Zeit, in der ein Formular aktiv ist, die Sprache geändert wird. Du musst also nur im OnCreate deiner Package-Formulare prüfen, was die aktuelle Sprache ist, und das Formular entsprechend übersetzen.
Bei nicht-modalen Formularen ist es komplizierter, und ich habe keine passende Methode parat, die mir gefällt. Du könntest natürlich, wenn die Sprache geändert worden ist, alle aktiven Formulare der Anwendung durchlaufen, ihren Typ prüfen und wenn es sich um ein Formular deines Packages handelt, nach einem Type-cast die nun bekannte Methode Translate aufrufen. Ist halt etwas sehr unförmig...
Eleganter wäre, an alle Formulare der Anwendung eine Nachricht zu schicken, die die Neuübersetzung anstößt. Aber da das keine Standard-Message ist, können Formulare aus anderen Packages damit nichts anfangen, selbst wenn sie mehrsprachen-fähig sind.
Oder du gehst den einfachen Weg, so wie die IDE: Du forderst nach einem Sprachenwechsel, dass die Anwendung neu gestartet werden muss. Jedes mehrsprachige Formular sollte in der Lage sein, bei einem erneuten Create die aktuelle Sprache abzufragen und sich entsprechend einzustellen.
Re: i18n für eine Form in einem Package
Okidoki.
In einem älteren mehrsprachigem Projekt habe ich ja auch eine methode die mir alle Captions und alles andere in allen Formularen zur Laufzeit ändert. Sind halt aber schon fast 1000 Zeilen code.
Aber ich weis ja wo alles ist und empfinde es auch nicht als unübersichtlich.
Dann werde ich das wohl oder übel nur mit ResourceStrings machen und muss dann gezielt Methoden nutzen um die Sprachänderung zur Laufzeit zugewährleisten.
Sprachen ändern und dann das Progg neu starten, finde ich nicht so dolle.
In einem älteren mehrsprachigem Projekt habe ich ja auch eine methode die mir alle Captions und alles andere in allen Formularen zur Laufzeit ändert. Sind halt aber schon fast 1000 Zeilen code.
Aber ich weis ja wo alles ist und empfinde es auch nicht als unübersichtlich.
Dann werde ich das wohl oder übel nur mit ResourceStrings machen und muss dann gezielt Methoden nutzen um die Sprachänderung zur Laufzeit zugewährleisten.
Sprachen ändern und dann das Progg neu starten, finde ich nicht so dolle.
Re: i18n für eine Form in einem Package
Ich hätte doch noch eine Frage:
Alle Resourcestrings die ich im Package vorbereite, kann ich die dann auch in der Projekt.po Datei verwalten , oder habe ich am ende zwei po-dateien für eine Sprache. Die vom Package und die vom Projekt?
Was wäre wenn man mehrer Packages hätte die alle selbst auch i18n nutzen.
Da hätte man ja am ende 5 oder mehr po-Dateien für eine Sprache.
Alle Resourcestrings die ich im Package vorbereite, kann ich die dann auch in der Projekt.po Datei verwalten , oder habe ich am ende zwei po-dateien für eine Sprache. Die vom Package und die vom Projekt?
Was wäre wenn man mehrer Packages hätte die alle selbst auch i18n nutzen.
Da hätte man ja am ende 5 oder mehr po-Dateien für eine Sprache.
Re: i18n für eine Form in einem Package
Genau. Jedes Package hat seine eigene po-Datei. Aber so soll es auch sein, denn ein Package wird von vielen Projekten verwendet.
In deinem Projekt kopierst du dann alle po-Dateien von allen verwendeten Packages ins Sprachverzeichnis deines Projekts. Mit Hilfe von TranslateUnitResourceStrings (unit Translations) musst du dann explizit nach dem Ändern der Sprache die Resourcestring-Dateien jedes Packages einzeln übersetzen.
Ich habe als Beispiel ein einfaches Chart-Programm beigefügt, das zwischen Englisch und Deutsch hinundherschaltet und die entsprechend übersetzten Strings anzeigt. Die Strings in der Combobox stammen dabei aus der po-Datei des TAChart-Packages, die anderen Strings sind im Hauptformular definiert und stehen in der Projekt-po-Datei.
In deinem Projekt kopierst du dann alle po-Dateien von allen verwendeten Packages ins Sprachverzeichnis deines Projekts. Mit Hilfe von TranslateUnitResourceStrings (unit Translations) musst du dann explizit nach dem Ändern der Sprache die Resourcestring-Dateien jedes Packages einzeln übersetzen.
Ich habe als Beispiel ein einfaches Chart-Programm beigefügt, das zwischen Englisch und Deutsch hinundherschaltet und die entsprechend übersetzten Strings anzeigt. Die Strings in der Combobox stammen dabei aus der po-Datei des TAChart-Packages, die anderen Strings sind im Hauptformular definiert und stehen in der Projekt-po-Datei.
- Dateianhänge
-
translated_chart.zip
- (14.63 KiB) 61-mal heruntergeladen
Re: i18n für eine Form in einem Package
Vielen Dank für das Beispiel Proggram.
Da kann ich mir noch einiges abschauen.
Mit dieser Methode werden die po-Dateien aus dem Package verarbeitet?
Und wenn ich das so richtig erkenne dann werden auch Component Captions automatisch in die po-Datei eingepflegt und ist dann für die Übersetzung im HauptForm zuständig.
Und übernimmt den rest der nicht automatisch in der HauptForm geändert wird.
Habe ich das soweit richtig verstanden?
Da kann ich mir noch einiges abschauen.
Code: Alles auswählen
TranslateUnitResourceStrings('TAChartStrConsts', 'languages/tachartstrconsts.%s.po',
ALang, ALang);
Und wenn ich das so richtig erkenne dann werden auch Component Captions automatisch in die po-Datei eingepflegt und
Code: Alles auswählen
SetDefaultLang(ALang);
Und
Code: Alles auswählen
TranslateForm;
Habe ich das soweit richtig verstanden?
Re: i18n für eine Form in einem Package
Ja, so habe ich mir das gedacht.
Bei TranslateUnitResourceStrings gibt es noch zwei, drei überladene Varianten, aber die genannte fand ich am einfachsten anzuwenden (einfach mit CTRL auf "TranslateUnitResourceStrings" klicken und der Editor öffnet die zugehörige Unit, und du kannst dann auch die anderen Varianten sehen).
Bei TranslateUnitResourceStrings gibt es noch zwei, drei überladene Varianten, aber die genannte fand ich am einfachsten anzuwenden (einfach mit CTRL auf "TranslateUnitResourceStrings" klicken und der Editor öffnet die zugehörige Unit, und du kannst dann auch die anderen Varianten sehen).
Re: i18n für eine Form in einem Package
OK, das gefällt mir.
Yo, ích schaue mir immer alle Komponenten genauer an, um zu wissen was da alles geht und was es für Methoden gibt usw.wp_xyz hat geschrieben: Mi 29. Sep 2021, 01:20 Bei TranslateUnitResourceStrings gibt es noch zwei, drei überladene Varianten, aber die genannte fand ich am einfachsten anzuwenden (einfach mit CTRL auf "TranslateUnitResourceStrings" klicken und der Editor öffnet die zugehörige Unit, und du kannst dann auch die anderen Varianten sehen).