Seite 1 von 1

verschiedene Sprachen unterstützen

Verfasst: 20.04.2014 17:34
von SBond
Hi Leute,

ich habe mal wieder eine Frage....

Ich schreibe gerade an einem Programm, das recht umfangreich wird. Ich habe es vorgesehen, dass der Benutzer die Sprache ändern kann (multilinguale GUI). ...aber wie mache ich das am besten? Hat jemand so etwas schon mal umgesetzt bzw. gibt es etwas auf das man besonders achten muss?

Ich habe gedacht, dass ich dazu eine XML-Datei erzeuge und darin verschiedene Sprachen speichere. Am Anfang wird es wohl Englisch und Deutsch sein. Das Erstellen und Auslesen dieser Datei stellt kein Problem dar. Interesant wird es, wenn ich die Sprache in der GUI nun ändere.

Statische Gadgets sind recht leicht mit SetGadgetText() umzubenennen. Problematisch wird es für mich z.B. bei Tooltips und Statusmeldungen, die Bedingungsabhängig erzeugt werden. Hier kann ich meiner Meinung nach nur mit Variablen arbeiten, die z.B. den String in der richtigen Sprache enthalten.
Das ist prinzipiell auch möglich, aber ich denke, dass die Lesbarkeit des Quellcodes stark abnimmt.

so wäre z.B. mein derzeitiger Code:

Code: Alles auswählen

If iStatus = #NO_ERROR
	SetStatustext("Es ist kein Fehler aufgetreten.")
	
ElseIf iStatus = #ERROR_BUFFER_OVERFLOW
	SetStatustext("FEHLER: Ein Pufferüberlauf wurde registriert!")
	
ElseIf iStatus = #ERROR_CRITICAL_VOLTAGE
	SetStatustext("FEHLER: die krittische Spannung wurde erreicht!")
	
EndIf

wenn ich die Sprachen in eine Struktur speichere, dann könnte ich so etwas machen:

Code: Alles auswählen

If iStatus = #NO_ERROR
	SetStatustext(Lang\sNo_Error)
	
ElseIf iStatus = #ERROR_BUFFER_OVERFLOW
	SetStatustext(Lang\sError_Buffer_Overflow)
	
ElseIf iStatus = #ERROR_CRITICAL_VOLTAGE
	SetStatustext(Lang\sError_Crit_Voltage)
	
EndIf
bzw so:

Code: Alles auswählen

If iStatus = #NO_ERROR:						SetStatustext(Lang\sNo_Error)				; Es ist kein Fehler aufgetreten.
ElseIf iStatus = #ERROR_BUFFER_OVERFLOW:	SetStatustext(Lang\sError_Buffer_Overflow)	; FEHLER: Ein Pufferüberlauf wurde registriert!
ElseIf iStatus = #ERROR_CRITICAL_VOLTAGE:	SetStatustext(Lang\sError_Crit_Voltage)		; FEHLER: die krittische Spannung wurde erreicht!
EndIf

Ist ein solches vorgehen sinnvoll? Aktuell habe ich ca. 220 Strings. Am Ende werden es ca. 800-1000 sein.

viele Grüße,
SBond

Re: verschiedene Sprachen unterstützen

Verfasst: 20.04.2014 17:43
von ts-soft
Ich nutze immer diese Vorlage von Freak: http://www.purebasic.fr/english/viewtop ... t=language

Gruß
Thomas

Re: verschiedene Sprachen unterstützen

Verfasst: 20.04.2014 17:52
von SBond
das ist interessant. So etwas habe ich noch gar nicht gesehen.

vielen Dank :)

Re: verschiedene Sprachen unterstützen

Verfasst: 21.04.2014 00:30
von _sivizius
Das läuft darauf hinaus, dass du alle Strings
1. einliest
2. indizierst
Einlesen kannst du das beliebig, z.B.
  • Einfache Textdatei, wobei jede Zeile = ein String. Einfach mit ReadString() einlesen.
  • Textdatei, wobei alle Strings mit \0 getrennt sind. Dazu einfach mit ReadData() einlesen und innerhalb des Buffers die Pointer berechnen.
  • Oberes kombiniert mit vTable.
  • Komprimiert, siehe Hilfe:Packer
  • Verschlüsselt, siehe Hilfe:Cipher
  • als .pref, siehe Hilfe:Preference
  • als .xml, siehe Hilfe:XML
  • in einem eigenem Format. Ich habe mir z.B. eine eigene Markup-Language entwickelt, die so etwas beinhaltet.
Für die Indizierung ist wohl ein einfaches Array geeignet. Da brauchst du eig auch keine großen Strukturen, kannst aber eine Struktur mit dem Array und einigen Zusatzinformationen anlegen.
Eine weitere Lösung wäre es, alles als eigene Library zu speichern(.so oder .dll), welche du mit OpenLibrary() einbindest. Darin könntest du Indizierung und Daten usw. schon beinhalten. Das ist dann aber OS spezifisch und man schießt mit Kanonen auf Spatzen :P

Re: verschiedene Sprachen unterstützen

Verfasst: 21.04.2014 01:05
von NicTheQuick
Ich würde ja eine globale Map nehmen und ein paar Funktionen drum herum bauen.

Code: Alles auswählen

Global NewMap LANG.s()

Procedure LoadGerman()
	LANG("Programmtitel") = "Mein Programm"
	LANG("Ladefehler") = "Laden der Datei %1 fehlgeschlagen."
	LANG("Fortschritt") = "Fortschritt: %1%%"
EndProcedure

Procedure LoadEnglish()
	LANG("Programmtitel") = "My Program"
	LANG("Ladefehler") = "Error loading file %1."
	LANG("Fortschritt") = "Progress: %1%%"
EndProcedure

Procedure.s TRANSLATE(s.s, para1.s = "", para2.s = "", para3.s = "")
	Protected t.s = LANG(s)
	t = ReplaceString(t, "%%", "%")
	t = ReplaceString(t, "%1", para1)
	t = ReplaceString(t, "%2", para2)
	t = ReplaceString(t, "%3", para3)
	ProcedureReturn t
EndProcedure

LoadGerman()

Debug TRANSLATE("Programmtitel")
Debug TRANSLATE("Ladefehler", "datei.dat")
Debug TRANSLATE("Fortschritt", "95")

LoadEnglish()

Debug TRANSLATE("Programmtitel")
Debug TRANSLATE("Ladefehler", "datei.dat")
Debug TRANSLATE("Fortschritt", "95")

Re: verschiedene Sprachen unterstützen

Verfasst: 21.04.2014 10:50
von Danilo
NicTheQuick hat geschrieben:Ich würde ja eine globale Map nehmen und ein paar Funktionen drum herum bauen.
Wenn der String in der Map nicht gefunden wird, würde ich aber den String selbst zurück geben, statt einen Leerstring. Hilft beim Debuggen.

In Deinem Beispiel bekommt man einen Leerstring:

Code: Alles auswählen

Debug TRANSLATE("Programtitel")
Siehe auch: tr()

__________________________________________________
Domain angepasst
21.04.2014
RSBasic

Re: verschiedene Sprachen unterstützen

Verfasst: 21.04.2014 12:14
von NicTheQuick
Danilo hat geschrieben:
NicTheQuick hat geschrieben:Ich würde ja eine globale Map nehmen und ein paar Funktionen drum herum bauen.
Wenn der String in der Map nicht gefunden wird, würde ich aber den String selbst zurück geben, statt einen Leerstring. Hilft beim Debuggen.
Das stimmt. Ich habe es sowieso nur mal eben dahin gecodet. Erweitern kann das jeder für sich, wenn er möchte. Ich selbst habe auch noch keine mehrsprachige Unterstützung in meine Programme eingebaut. Lediglich für einen Webshop habe ich das mal gemacht, aber der ist leider nicht mehr online.

Re: verschiedene Sprachen unterstützen

Verfasst: 21.04.2014 21:14
von SBond
super :)


vielen Dank für die Ratschläge. Maps habe ich noch nie verwendet, aber irgendwann ist ja immer das erste mal ;)