Zielsetzung der hier beschriebenen Übersetzungssystematik ist es einerseits String-Literale möglichst direkt in der Programmquelle definieren zu können, andererseits aber eine Übersetzung dieser Literale zur Laufzeit in die vom Benutzer gewünschte Sprache (z. B. Englisch) zu erreichen.
Zusätzlich besteht der Anspruch, alle zur Laufzeit zu übersetzenden String-Literale durch Analyse der Programmquellen herausfinden und zusammenstellen zu können.
String-Literale sind in den Programmquellen auf deutsch zu hinterlegen. Durch Einstellung einer gewünschten Zielsprache, werden diese dann zur Laufzeit in eine andere Sprache, z. B. Englisch, übersetzt.
Zu SOG ERP Kunden wird eine vorbereitete Übersetzungstabelle für alle hinterlegten String-Literale ins Englische ausgeliefert.
Damit zu übersetzende String-Literale zusammengestellt werden können, müssen diese durch das Einkleiden in bestimmte Signal-Funktionen (Translate und Format, siehe unten) deklariert werden.
Im Zuge des Kommandos TextEx werden dann alle Programmquellen nach diesen Signal-Funktionen durchsucht und die dort definierten String-Literale extrahiert.
Einfache Übersetzung von Texten:
Die Funktion "Translate" des aktuellen AppHelper übersetzt ein konstantes String-Literal.
AppHelper.Current.Translate("Das ist ein Text");
Besondere Vorsicht ist geboten, wenn der zu übersetzende Text mit Daten angereichert werden soll. Da jeder neue Text, der an die Übersetzungsengine geschickt wird, auch neu übersetzt und gecacht werden muss muss vermieden werden, Texte in denen ständig wechselnde Daten eingetragen sind (z. B. Kontonummer), an den Übersetzer zu schicken. Stattdessen muss ein String mit Platzhaltern verwendet werden. Dieser wird bei der Übersetzung wiederum in einen übersetzten Text mit Platzhaltern gewandelt, muss also nicht für jede Kontonummer erneut und damit ggf. tausendfach übersetzt und in der Cach-Datenbank gespeichert werden.
Für einen bequemen Aufruf bietet der aktuelle AppHelper eine Formatfunktion zur Übersetzung an.
AppHelper.Current.Format("Das ist ein Text der die Kontonummer {0} enthält", konto);
Alternativ kann die Funktion "Translate" auch mit einem interpolierten String aufgerufen werden:
AppHelper.Current.Translate($"Das ist ein Text der die Kontonummer {konto} enthält");
Die Funktionen Translate und Format haben zusätzlich den Nutzen, dass alle Quellen nach Textkonserven durchsucht werden, die in Translate und Format verwendet wurden, um so eine Liste aller zu übersetzenden Texte zusammenzustellen. Daher dürfen in Translate und Format wirklich nur konstante Literale verwendet werden.
Zur Übersetzung von Resourcen, z. B. in Xml-Dateien definierte Texte, steht folgende Funktion zur Verfügung:
SOGTranslate.TranslateResource( datenfeld )
Die Funktion TranslateResource übersetzt den übergebenen Text, allerdings erfolgt keine automatische Erkennung der Übergaben bei der Analyse des Quellcodes. Es muss also anderweitig sichergestellt werden, dass die Texte in den Resourcen-Dateien in die Liste der zu übersetzenden Texte aufgenommen werden.
Es ist darauf zu achten, dass Translate und Format wirklich nur mit konstanten Literalen verwendet werden, da diese bei der Analyse der Quellen als zu übersetzende Textkonserve erkannt und gelistet werden.
Übersetzen von Fehlermeldungen
Damit Fehlermeldungen zum einen für den Anwender übersetzt werden, zum anderen aber in die Protokoll in nicht übersetzter Form z. B. für die SOG Hotline zur Verfügung stehen, wurde die Klasse SOGLogText entwickelt. Fehlermeldungen, die in einem SOGLogText stehen, werden erst dann übersetzt, wenn sie dem Anwender angezeigt werden sollen, als ggf. erst von dem Dialogprogramm "Logbuchanzeige (hhdsplg4)" sofern hier eine Sprache abweichend von "ger" für Deutsch zur Anzeige eingestellt wurde.
AppHelper.Current.FormatLog("Das ist eine Fehlermeldung die eine Kontonummer {0} enthält", konto);
Alternativ kann hier auch die Funktion "TranslateLog" mit einem interpolierten String aufgerufen werden:
AppHelper.Current.TranslateLog($"Das ist eine Fehlermeldung die eine Kontonummer {konto} enthält");
Um an Funktionen die einen SOGLogText erwarten einen einfachen Text, der nicht übersetzbar ist, übergeben zu können, steht die Funktion "CreateUntranslateable" zur Verfügung.
Dieser kann z. B. verwendet werden, um fremde Fehlermeldungen, an die SOG Log-Routinen durchzureichen.
SOGLogText.CreateUntranslateable( ex.Message );
Die Klasse TranslatedString ist dazu geschaffen worden, um Klarheit bei dem Aufruf von Funktionen zu bekommen, ob an einer bestimmten Stelle ein bereits fertig übersetzter Text übergeben werden soll, oder nicht. Funktionen die ein TranslatedString Argument erwarten, erinnern den Programmierer also daran, hier eine Textübersetzung durchzuführen. Außerdem kann damit sichergestellt werden, dass ein bereits fertig übersetzter Text nicht erneut übersetzt wird. Bei der Verwendung von TranslatedStrings wird der Entwickler ebenso daran erinnert, dass der Text bereits fertig übersetzt ist, und keine Nachbehandlung erfordert.
TranslatedString ist also nur ein kleiner Container, der einen fertig übersetzten Text aufbewahrt und zur Verwendung bereit hält.
Zum Erzeugen von TranslatedString stehen unterschiedliche Möglichkeiten zur Verfügung
Die "Create" Funktion verpackt einen fertig übersetzten Text.
TranslatedString.Create( AppHelper.Current.Translate("Das ist ein Text") );
Dies kann z. B. auch dann verwendet werden, wenn der fertig übersetzte Text aus einer anderen Quelle (z. B. f077) stammt:
AreYouSureHelper.AreYouSure(
TranslatedString.Create(sp102.m_sp_t114.Value),
TranslatedString.Create(sp102.m_sp_t111.Value),
0, SOGMessageBoxButtons.OK, SOGMessageBoxIcon.Error);
Die "CreateUntranslateable" Funktion verpackt einen nicht übersetzbaren Text. In diesem Beispiel, den Text einer Systemfehlermeldung.
TranslatedString.CreateUntranslateable( ex.Message );
Die Klasse TranslatedString bietet auch Schnellfunktionen an, die das Übersetzen von Litralen und Resourcen und Wandeln in einen TranslatedString in einem Aufruf ermöglichen.
TranslatedString.Translate("Das ist ein Text");
TranslatedString.Format("Das ist ein Text der die Kontonummer {0} enthält", konto);
TranslatedString.Translate($"Das ist ein Text der die Kontonummer {konto} enthält");
TranslatedString.TranslateResource( datenfeld )
Die Funktionen haben die gleiche Wirkung wie die entsprechenden AppHelper.Current Funktionen, liefern aber einen TranslatedString.
Auch hier ist darauf zu achten, dass Translate und Format wirklich nur mit konstanten Literalen verwendet werden, da diese bei der Analyse der Quellen als zu übersetzende Textkonserve erkannt und gelistet werden.
An einigen Stellen in der ERP Software werden Menüs durch die Angabe von Pfaden im Format /Verzeichnis/Unterverzeichnis/Menüpunkt definiert.
Solche Resourcen in einem Pfad-Format, dürfen nicht als Text komplett übersetzt werden. Die Übersetzungsengine muss vielmehr den Pfad in Einzelteile zerlegen, und jeden Teil für sich übersetzen.
In diesem Beispiel also die Worte "Verzeichnis", "Unterverzeichnis" und "Menüpunkt". Anschließend muss das Ergebnis wieder zu einem Pfad zusammengefügt werden:
/Directory/Subdirectory/Menuentry
Für diese Funktionalität stehen spezielle Übersetzungsfunktionen zur Verfügung:
AppHelper.TranslatePath("/Verzeichnis/Unterverzeichnis/Menüpunkt")
SOGTranslate.TranslateResourcePath( textvariable );
TranslatedString.TranslatePath("/Verzeichnis/Unterverzeichnis/Menüpunkt")
TranslatedString.TranslateResourcePath( textvariable );
Die ersten Funktionen liefern als Rückgabewerte "string", die letzten "TranslatedString".
Die TranslatePath Funktionen dürfen wieder nur mit einem konstanten String-Literal verwendet werden.
Die Klasse CompleteTranslation ermöglicht das Übersetzen von Texten unter Beibehaltung des Original nicht übersetzten Textes. CompleteTranslation ist eine Ableitung von TranslatedString und kann daher überall verwendet werden, wo TranslatedString erwartet wird. Auswahllisten liefern in den meisten Fällen ein "CompleteTranslation" Objekt, damit ggf. auf den Original nicht übersetzten Begriff zugegriffen werden kann.
Das ist jedoch nicht verlässlich.
CompleteTranslation bietet folgende Statische Funktionen, zur Erzeugung eines CompletetTranslation Objektes.
CompleteTranslation.Translate("Das ist ein Text");
CompleteTranslation.Format("Das ist ein Text der die Kontonummer {0} enthält", konto);
CompleteTranslation.Translate($"Das ist ein Text der die Kontonummer {konto} enthält");
CompleteTranslation.TranslatePath("/Verzeichnis/Unterverzeichnis/Menüpunkt")
CompleteTranslation.TranslateResource( datenfeld )
CompleteTranslation.CreateUntranslateable( datenfeld )