Added translation support to Godot

included is a French translation!
This commit is contained in:
Juan Linietsky 2016-05-27 19:58:28 -03:00
parent 8be2fabbe5
commit bccdc11dde
10 changed files with 5847 additions and 13 deletions

1
.gitignore vendored
View file

@ -19,6 +19,7 @@ tools/editor/register_exporters.cpp
tools/editor/doc_data_compressed.h tools/editor/doc_data_compressed.h
tools/editor/certs_compressed.h tools/editor/certs_compressed.h
tools/editor/editor_icons.cpp tools/editor/editor_icons.cpp
tools/editor/translations.h
-fpic -fpic
.fscache .fscache
make.bat make.bat

View file

@ -135,7 +135,7 @@ size_t FileAccessMemory::get_len() const {
bool FileAccessMemory::eof_reached() const { bool FileAccessMemory::eof_reached() const {
return pos >= length; return pos > length;
} }
uint8_t FileAccessMemory::get_8() const { uint8_t FileAccessMemory::get_8() const {

View file

@ -30,13 +30,8 @@
#include "os/file_access.h" #include "os/file_access.h"
#include "translation.h" #include "translation.h"
RES TranslationLoaderPO::load(const String &p_path, const String& p_original_path, Error *r_error) {
if (r_error) RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error, const String &p_path) {
*r_error=ERR_CANT_OPEN;
FileAccess *f=FileAccess::open(p_path,FileAccess::READ);
ERR_FAIL_COND_V(!f,RES());
String l = f->get_line(); String l = f->get_line();
@ -52,6 +47,8 @@ RES TranslationLoaderPO::load(const String &p_path, const String& p_original_pat
String msg_id; String msg_id;
String msg_str; String msg_str;
String config; String config;
int msg_line=0;
if (r_error) if (r_error)
*r_error=ERR_FILE_CORRUPT; *r_error=ERR_FILE_CORRUPT;
@ -87,7 +84,7 @@ RES TranslationLoaderPO::load(const String &p_path, const String& p_original_pat
if (status==STATUS_READING_ID) { if (status==STATUS_READING_ID) {
memdelete(f); memdelete(f);
ERR_EXPLAIN(p_path+":"+itos(line)+" nexpected 'msgid', was expecting 'msgstr' while parsing: "); ERR_EXPLAIN(p_path+":"+itos(line)+" Unexpected 'msgid', was expecting 'msgstr' while parsing: ");
ERR_FAIL_V(RES()); ERR_FAIL_V(RES());
} }
@ -100,6 +97,7 @@ RES TranslationLoaderPO::load(const String &p_path, const String& p_original_pat
status=STATUS_READING_ID; status=STATUS_READING_ID;
msg_id=""; msg_id="";
msg_str=""; msg_str="";
msg_line=line;
} }
if (l.begins_with("msgstr")) { if (l.begins_with("msgstr")) {
@ -113,6 +111,7 @@ RES TranslationLoaderPO::load(const String &p_path, const String& p_original_pat
l=l.substr(6,l.length()).strip_edges(); l=l.substr(6,l.length()).strip_edges();
status=STATUS_READING_STRING; status=STATUS_READING_STRING;
msg_line=line;
} }
if (l=="" || l.begins_with("#")) { if (l=="" || l.begins_with("#")) {
@ -183,6 +182,18 @@ RES TranslationLoaderPO::load(const String &p_path, const String& p_original_pat
*r_error=OK; *r_error=OK;
return translation; return translation;
}
RES TranslationLoaderPO::load(const String &p_path, const String& p_original_path, Error *r_error) {
if (r_error)
*r_error=ERR_CANT_OPEN;
FileAccess *f=FileAccess::open(p_path,FileAccess::READ);
ERR_FAIL_COND_V(!f,RES());
return load_translation(f,r_error);
} }

View file

@ -30,10 +30,12 @@
#define TRANSLATION_LOADER_PO_H #define TRANSLATION_LOADER_PO_H
#include "io/resource_loader.h" #include "io/resource_loader.h"
#include "translation.h"
#include "os/file_access.h"
class TranslationLoaderPO : public ResourceFormatLoader { class TranslationLoaderPO : public ResourceFormatLoader {
public: public:
static RES load_translation(FileAccess *f, Error *r_error,const String& p_path=String());
virtual RES load(const String &p_path,const String& p_original_path="",Error *r_error=NULL); virtual RES load(const String &p_path,const String& p_original_path="",Error *r_error=NULL);
virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String& p_type) const; virtual bool handles_type(const String& p_type) const;

View file

@ -85,6 +85,7 @@ enum PropertyUsageFlags {
PROPERTY_USAGE_STORE_IF_NONZERO=512, //only store if nonzero PROPERTY_USAGE_STORE_IF_NONZERO=512, //only store if nonzero
PROPERTY_USAGE_STORE_IF_NONONE=1024, //only store if false PROPERTY_USAGE_STORE_IF_NONONE=1024, //only store if false
PROPERTY_USAGE_NO_INSTANCE_STATE=2048, PROPERTY_USAGE_NO_INSTANCE_STATE=2048,
PROPERTY_USAGE_RESTART_IF_CHANGED=4096,
PROPERTY_USAGE_DEFAULT=PROPERTY_USAGE_STORAGE|PROPERTY_USAGE_EDITOR|PROPERTY_USAGE_NETWORK, PROPERTY_USAGE_DEFAULT=PROPERTY_USAGE_STORAGE|PROPERTY_USAGE_EDITOR|PROPERTY_USAGE_NETWORK,
PROPERTY_USAGE_DEFAULT_INTL=PROPERTY_USAGE_STORAGE|PROPERTY_USAGE_EDITOR|PROPERTY_USAGE_NETWORK|PROPERTY_USAGE_INTERNATIONALIZED, PROPERTY_USAGE_DEFAULT_INTL=PROPERTY_USAGE_STORAGE|PROPERTY_USAGE_EDITOR|PROPERTY_USAGE_NETWORK|PROPERTY_USAGE_INTERNATIONALIZED,

View file

@ -672,10 +672,12 @@ void TranslationServer::set_tool_translation(const Ref<Translation>& p_translati
StringName TranslationServer::tool_translate(const StringName& p_message) const { StringName TranslationServer::tool_translate(const StringName& p_message) const {
if (tool_translation.is_valid()) { if (tool_translation.is_valid()) {
StringName r = tool_translation->tr(p_message); StringName r = tool_translation->get_message(p_message);
if (r)
if (r) {
return r; return r;
} }
}
return p_message; return p_message;
} }

View file

@ -5,7 +5,71 @@ env.add_source_files(env.tool_sources,"*.cpp")
Export('env') Export('env')
def make_translations_header(target,source,env):
dst = target[0].srcnode().abspath
g = open(dst,"wb")
""""
"""
g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
g.write("#ifndef _EDITOR_TRANSLATIONS_H\n")
g.write("#define _EDITOR_TRANSLATIONS_H\n")
xl_names=[]
for i in range(len(source)):
print("Appending translation: "+source[i].srcnode().abspath)
f = open(source[i].srcnode().abspath,"rb")
buf = f.read()
decomp_size = len(buf)
import zlib
import os.path
buf = zlib.compress(buf)
name = os.path.splitext(os.path.basename(source[i].srcnode().abspath))[0]
#g.write("static const int _translation_"+name+"_compressed_size="+str(len(buf))+";\n")
#g.write("static const int _translation_"+name+"_uncompressed_size="+str(decomp_size)+";\n")
g.write("static const unsigned char _translation_"+name+"_compressed[]={\n")
for i in range(len(buf)):
g.write(str(ord(buf[i]))+",\n")
g.write("};\n")
xl_names.append([name,len(buf),str(decomp_size)])
g.write("struct EditorTranslationList {\n")
g.write("\tconst char* lang;\n");
g.write("\tint comp_size;\n");
g.write("\tint uncomp_size;\n");
g.write("\tconst unsigned char* data;\n");
g.write("};\n\n");
g.write("static EditorTranslationList _editor_translations[]={\n")
for x in xl_names:
g.write("\t{ \""+x[0]+"\", "+str(x[1])+", "+str(x[2])+",_translation_"+x[0]+"_compressed},\n")
g.write("\t{NULL,0,0,NULL}\n")
g.write("};\n")
g.write("#endif")
if (env["tools"]!="no"): if (env["tools"]!="no"):
import glob
dir = env.Dir('.').abspath
tlist = glob.glob(dir + "/translations/*.po")
print("translations: ",tlist)
env.Depends('#tools/editor/translations.h',tlist)
env.Command('#tools/editor/translations.h',tlist,make_translations_header)
SConscript('editor/SCsub'); SConscript('editor/SCsub');
#SConscript('scintilla/SCsub'); #SConscript('scintilla/SCsub');
SConscript('collada/SCsub'); SConscript('collada/SCsub');

View file

@ -41,6 +41,10 @@
#include "io/config_file.h" #include "io/config_file.h"
#include "editor_node.h" #include "editor_node.h"
#include "globals.h" #include "globals.h"
#include "translations.h"
#include "io/file_access_memory.h"
#include "io/translation_loader_po.h"
#include "io/compression.h"
Ref<EditorSettings> EditorSettings::singleton=NULL; Ref<EditorSettings> EditorSettings::singleton=NULL;
@ -284,6 +288,7 @@ void EditorSettings::create() {
print_line("EditorSettings: Load OK!"); print_line("EditorSettings: Load OK!");
} }
singleton->setup_language();
singleton->setup_network(); singleton->setup_network();
singleton->load_favorites(); singleton->load_favorites();
singleton->list_text_editor_themes(); singleton->list_text_editor_themes();
@ -310,9 +315,11 @@ void EditorSettings::create() {
singleton->config_file_path=config_file_path; singleton->config_file_path=config_file_path;
singleton->settings_path=config_path+"/"+config_dir; singleton->settings_path=config_path+"/"+config_dir;
singleton->_load_defaults(extra_config); singleton->_load_defaults(extra_config);
singleton->setup_language();
singleton->setup_network(); singleton->setup_network();
singleton->list_text_editor_themes(); singleton->list_text_editor_themes();
} }
String EditorSettings::get_settings_path() const { String EditorSettings::get_settings_path() const {
@ -322,6 +329,23 @@ String EditorSettings::get_settings_path() const {
void EditorSettings::setup_language() {
String lang = get("global/editor_language");
print_line("LANG IS "+lang);
if (lang=="en")
return; //none to do
for(int i=0;i<translations.size();i++) {
print_line("TESTING "+translations[i]->get_locale());
if (translations[i]->get_locale()==lang) {
print_line("ok translation");
TranslationServer::get_singleton()->set_tool_translation(translations[i]);
break;
}
}
}
void EditorSettings::setup_network() { void EditorSettings::setup_network() {
List<IP_Address> local_ip; List<IP_Address> local_ip;
@ -389,6 +413,36 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
_THREAD_SAFE_METHOD_ _THREAD_SAFE_METHOD_
{
String lang_hint="en";
String host_lang = OS::get_singleton()->get_locale();
String best;
for(int i=0;i<translations.size();i++) {
String locale = translations[i]->get_locale();
lang_hint+=",";
lang_hint+=locale;
if (host_lang==locale) {
best=locale;
}
if (best==String() && host_lang.begins_with(locale)) {
best=locale;
}
}
if (best==String()) {
best="en";
}
set("global/editor_language",best);
hints["global/editor_language"]=PropertyInfo(Variant::STRING,"global/editor_language",PROPERTY_HINT_ENUM,lang_hint,PROPERTY_USAGE_DEFAULT|PROPERTY_USAGE_RESTART_IF_CHANGED);
}
set("global/show_script_in_scene_tabs",false);
set("global/font",""); set("global/font","");
hints["global/font"]=PropertyInfo(Variant::STRING,"global/font",PROPERTY_HINT_GLOBAL_FILE,"*.fnt"); hints["global/font"]=PropertyInfo(Variant::STRING,"global/font",PROPERTY_HINT_GLOBAL_FILE,"*.fnt");
set("global/autoscan_project_path",""); set("global/autoscan_project_path","");
@ -399,6 +453,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
hints["global/default_project_export_path"]=PropertyInfo(Variant::STRING,"global/default_project_export_path",PROPERTY_HINT_GLOBAL_DIR); hints["global/default_project_export_path"]=PropertyInfo(Variant::STRING,"global/default_project_export_path",PROPERTY_HINT_GLOBAL_DIR);
set("global/show_script_in_scene_tabs",false); set("global/show_script_in_scene_tabs",false);
set("text_editor/color_theme","Default"); set("text_editor/color_theme","Default");
hints["text_editor/color_theme"]=PropertyInfo(Variant::STRING,"text_editor/color_theme",PROPERTY_HINT_ENUM,"Default"); hints["text_editor/color_theme"]=PropertyInfo(Variant::STRING,"text_editor/color_theme",PROPERTY_HINT_ENUM,"Default");
@ -821,7 +876,32 @@ EditorSettings::EditorSettings() {
//singleton=this; //singleton=this;
last_order=0; last_order=0;
EditorTranslationList *etl=_editor_translations;
while(etl->data) {
Vector<uint8_t> data;
data.resize(etl->uncomp_size);
Compression::decompress(data.ptr(),etl->uncomp_size,etl->data,etl->comp_size,Compression::MODE_DEFLATE);
FileAccessMemory *fa = memnew (FileAccessMemory);
fa->open_custom(data.ptr(),data.size());
Ref<Translation> tr = TranslationLoaderPO::load_translation(fa,NULL,"translation_"+String(etl->lang));
if (tr.is_valid()) {
tr->set_locale(etl->lang);
translations.push_back(tr);
}
etl++;
}
_load_defaults(); _load_defaults();
} }

View file

@ -34,7 +34,7 @@
#include "resource.h" #include "resource.h"
#include "os/thread_safe.h" #include "os/thread_safe.h"
#include "core/io/config_file.h" #include "core/io/config_file.h"
#include "translation.h"
class EditorPlugin; class EditorPlugin;
class EditorSettings : public Resource { class EditorSettings : public Resource {
@ -93,6 +93,8 @@ private:
Vector<String> favorite_dirs; Vector<String> favorite_dirs;
Vector<String> recent_dirs; Vector<String> recent_dirs;
Vector<Ref<Translation> > translations;
protected: protected:
static void _bind_methods(); static void _bind_methods();
@ -111,6 +113,7 @@ public:
String get_project_settings_path() const; String get_project_settings_path() const;
void setup_language();
void setup_network(); void setup_network();
void raise_order(const String& p_name); void raise_order(const String& p_name);

5670
tools/translations/fr.po Normal file

File diff suppressed because it is too large Load diff