Added translation support to Godot
included is a French translation!
This commit is contained in:
parent
8be2fabbe5
commit
bccdc11dde
10 changed files with 5847 additions and 13 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -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
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
64
tools/SCsub
64
tools/SCsub
|
@ -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');
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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
5670
tools/translations/fr.po
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue