Eric Hofman:
Now the options can be localized as well. This adds a slight problem for the --language options, but not that much (worst case, the strings are loaded twice consuming some more memory). I tried to be as accurate as posiible when copying the options texts, but there might be some mostakes left.
This commit is contained in:
parent
83314d3f45
commit
470d233f0d
5 changed files with 184 additions and 131 deletions
9
Thanks
9
Thanks
|
@ -172,6 +172,7 @@ Erik Hofman <erik@ehofman.com>
|
||||||
Major overhaul and parameterization of the sound module, to allow
|
Major overhaul and parameterization of the sound module, to allow
|
||||||
aircraft-specific sound configuration at runtime.
|
aircraft-specific sound configuration at runtime.
|
||||||
Irix port.
|
Irix port.
|
||||||
|
Localization support.
|
||||||
|
|
||||||
|
|
||||||
Charlie Hotchkiss <clhotch@pacbell.net>
|
Charlie Hotchkiss <clhotch@pacbell.net>
|
||||||
|
@ -233,6 +234,7 @@ David Megginson <david@megginson.com>
|
||||||
3D model animation module
|
3D model animation module
|
||||||
initial take of sound-effects module
|
initial take of sound-effects module
|
||||||
Random ground cover objects
|
Random ground cover objects
|
||||||
|
Vacuum and pitot systems.
|
||||||
|
|
||||||
|
|
||||||
Eric Mitchell <mitchell@mars.ark.com>
|
Eric Mitchell <mitchell@mars.ark.com>
|
||||||
|
@ -278,6 +280,8 @@ Curt Olson <curt@flightgear.org>
|
||||||
He has his hands in many of the areas, but is primarily responsible
|
He has his hands in many of the areas, but is primarily responsible
|
||||||
for the scenery subsystem, as well as much of the infrastructure in
|
for the scenery subsystem, as well as much of the infrastructure in
|
||||||
the sim.
|
the sim.
|
||||||
|
Electrical system.
|
||||||
|
Runway lighting.
|
||||||
|
|
||||||
|
|
||||||
Brian Paul
|
Brian Paul
|
||||||
|
@ -466,6 +470,11 @@ Jean-Claude Wippler <jcw@equi4.com>
|
||||||
http://www.equi4.com/metakit
|
http://www.equi4.com/metakit
|
||||||
|
|
||||||
|
|
||||||
|
John Wojnaroski <castle@mminternet.com>
|
||||||
|
Open Glass Cockpit project
|
||||||
|
3d clouds
|
||||||
|
|
||||||
|
|
||||||
WoodSoup Project http://www.woodsoup.org
|
WoodSoup Project http://www.woodsoup.org
|
||||||
[ FlightGear no longer uses woodsoup services, but we appreciate
|
[ FlightGear no longer uses woodsoup services, but we appreciate
|
||||||
the support provided to our project during the time they hosted us. ]
|
the support provided to our project during the time they hosted us. ]
|
||||||
|
|
|
@ -228,6 +228,120 @@ string fgBasePackageVersion() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Initialize the localization
|
||||||
|
SGPropertyNode *fgInitLocale(const char *language) {
|
||||||
|
SGPropertyNode *c_node = NULL, *d_node = NULL;
|
||||||
|
SGPropertyNode *intl = fgGetNode("/sim/intl");
|
||||||
|
|
||||||
|
SG_LOG(SG_GENERAL, SG_INFO, "Selecting language: " << language );
|
||||||
|
|
||||||
|
// localization not defined
|
||||||
|
if (!intl)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Select the proper language from the list
|
||||||
|
//
|
||||||
|
vector<SGPropertyNode_ptr> locale = intl->getChildren("locale");
|
||||||
|
for (unsigned int i = 0; i < locale.size(); i++) {
|
||||||
|
|
||||||
|
vector<SGPropertyNode_ptr> lang = locale[i]->getChildren("lang");
|
||||||
|
for (unsigned int j = 0; j < lang.size(); j++) {
|
||||||
|
|
||||||
|
if (!strcmp(lang[j]->getStringValue(), language)) {
|
||||||
|
c_node = locale[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Get the defaults
|
||||||
|
d_node = intl->getChild("locale");
|
||||||
|
if (!c_node)
|
||||||
|
c_node = d_node;
|
||||||
|
|
||||||
|
// Check for localized font
|
||||||
|
SGPropertyNode *font_n = c_node->getNode("font", true);
|
||||||
|
if ( !strcmp(font_n->getStringValue(), "") )
|
||||||
|
font_n->setStringValue(d_node->getStringValue("font", "typewriter.txf"));
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Load the default strings
|
||||||
|
//
|
||||||
|
SGPath d_path( globals->get_fg_root() );
|
||||||
|
|
||||||
|
const char *d_path_str = d_node->getStringValue("strings");
|
||||||
|
if (!d_path_str) {
|
||||||
|
SG_LOG(SG_GENERAL, SG_ALERT, "Incorrect path in configuration file.");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
d_path.append(d_path_str);
|
||||||
|
SG_LOG(SG_GENERAL, SG_INFO, "Reading localized strings from "
|
||||||
|
<< d_path.str());
|
||||||
|
|
||||||
|
SGPropertyNode *strings = c_node->getNode("strings");
|
||||||
|
try {
|
||||||
|
readProperties(d_path.str(), strings);
|
||||||
|
} catch (const sg_exception &e) {
|
||||||
|
SG_LOG(SG_GENERAL, SG_ALERT, "Unable to read the localized strings");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Load the language specific strings
|
||||||
|
//
|
||||||
|
if (c_node != d_node) {
|
||||||
|
SGPath c_path( globals->get_fg_root() );
|
||||||
|
|
||||||
|
const char *c_path_str = c_node->getStringValue("strings");
|
||||||
|
if (!c_path_str) {
|
||||||
|
SG_LOG(SG_GENERAL, SG_ALERT, "Incorrect path in configuration file.");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
c_path.append(c_path_str);
|
||||||
|
SG_LOG(SG_GENERAL, SG_INFO, "Reading localized strings from "
|
||||||
|
<< c_path.str());
|
||||||
|
|
||||||
|
try {
|
||||||
|
readProperties(c_path.str(), strings);
|
||||||
|
} catch (const sg_exception &e) {
|
||||||
|
SG_LOG(SG_GENERAL, SG_ALERT, "Unable to read the localized strings");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return c_node;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Initialize the localization routines
|
||||||
|
bool fgDetectLanguage() {
|
||||||
|
char *language = ::getenv("LANG");
|
||||||
|
|
||||||
|
if (language == NULL) {
|
||||||
|
SG_LOG(SG_GENERAL, SG_INFO, "Unable to detect the language" );
|
||||||
|
language = "C";
|
||||||
|
}
|
||||||
|
|
||||||
|
SGPropertyNode *locale = fgInitLocale(language);
|
||||||
|
if (!locale) {
|
||||||
|
cerr << "No internationalization settings specified in preferences.xml"
|
||||||
|
<< endl;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
globals->set_locale( locale );
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Read in configuration (file and command line)
|
// Read in configuration (file and command line)
|
||||||
bool fgInitConfig ( int argc, char **argv ) {
|
bool fgInitConfig ( int argc, char **argv ) {
|
||||||
|
|
||||||
|
@ -241,6 +355,10 @@ bool fgInitConfig ( int argc, char **argv ) {
|
||||||
readProperties(props_path.str(), globals->get_props());
|
readProperties(props_path.str(), globals->get_props());
|
||||||
SG_LOG(SG_INPUT, SG_INFO, "Finished Reading global preferences");
|
SG_LOG(SG_INPUT, SG_INFO, "Finished Reading global preferences");
|
||||||
|
|
||||||
|
// Detect the required language as early as possible
|
||||||
|
if (fgDetectLanguage() != true)
|
||||||
|
return false;
|
||||||
|
|
||||||
// Read the default aircraft config file.
|
// Read the default aircraft config file.
|
||||||
string aircraft = fgGetString("/sim/aircraft", "");
|
string aircraft = fgGetString("/sim/aircraft", "");
|
||||||
if (aircraft.size() > 0) {
|
if (aircraft.size() > 0) {
|
||||||
|
@ -302,96 +420,6 @@ bool fgInitConfig ( int argc, char **argv ) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize the localization
|
|
||||||
SGPropertyNode *fgInitLocale(const char *language) {
|
|
||||||
SGPropertyNode *c_node = NULL, *d_node = NULL;
|
|
||||||
SGPropertyNode *intl = fgGetNode("/sim/intl");
|
|
||||||
|
|
||||||
SG_LOG(SG_GENERAL, SG_INFO, "Selecting language: " << language );
|
|
||||||
|
|
||||||
// localization not defined
|
|
||||||
if (!intl)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Select the proper language from the list
|
|
||||||
//
|
|
||||||
vector<SGPropertyNode_ptr> locale = intl->getChildren("locale");
|
|
||||||
for (unsigned int i = 0; i < locale.size(); i++) {
|
|
||||||
|
|
||||||
vector<SGPropertyNode_ptr> lang = locale[i]->getChildren("lang");
|
|
||||||
for (unsigned int j = 0; j < lang.size(); j++) {
|
|
||||||
|
|
||||||
if (!strcmp(lang[j]->getStringValue(), language)) {
|
|
||||||
c_node = locale[i];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Get the defaults
|
|
||||||
d_node = intl->getChild("locale");
|
|
||||||
if (!c_node)
|
|
||||||
c_node = d_node;
|
|
||||||
|
|
||||||
// Check for localized font
|
|
||||||
SGPropertyNode *font_n = c_node->getNode("font", true);
|
|
||||||
if ( !strcmp(font_n->getStringValue(), "") )
|
|
||||||
font_n->setStringValue(d_node->getStringValue("font", "typewriter.txf"));
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// Load the default strings
|
|
||||||
//
|
|
||||||
SGPath d_path( globals->get_fg_root() );
|
|
||||||
|
|
||||||
const char *d_path_str = d_node->getStringValue("strings");
|
|
||||||
if (!d_path_str) {
|
|
||||||
SG_LOG(SG_GENERAL, SG_ALERT, "Incorrect path in configuration file.");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
d_path.append(d_path_str);
|
|
||||||
SG_LOG(SG_GENERAL, SG_INFO, "Reading localized strings from "
|
|
||||||
<< d_path.str());
|
|
||||||
|
|
||||||
SGPropertyNode *strings = c_node->getNode("strings");
|
|
||||||
try {
|
|
||||||
readProperties(d_path.str(), strings);
|
|
||||||
} catch (const sg_exception &e) {
|
|
||||||
SG_LOG(SG_GENERAL, SG_ALERT, "Unable to read the localized strings");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// Load the language specific strings
|
|
||||||
//
|
|
||||||
if (c_node != d_node) {
|
|
||||||
SGPath c_path( globals->get_fg_root() );
|
|
||||||
|
|
||||||
const char *c_path_str = c_node->getStringValue("strings");
|
|
||||||
if (!c_path_str) {
|
|
||||||
SG_LOG(SG_GENERAL, SG_ALERT, "Incorrect path in configuration file.");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
c_path.append(c_path_str);
|
|
||||||
SG_LOG(SG_GENERAL, SG_INFO, "Reading localized strings from "
|
|
||||||
<< c_path.str());
|
|
||||||
|
|
||||||
try {
|
|
||||||
readProperties(c_path.str(), strings);
|
|
||||||
} catch (const sg_exception &e) {
|
|
||||||
SG_LOG(SG_GENERAL, SG_ALERT, "Unable to read the localized strings");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return c_node;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// find basic airport location info from airport database
|
// find basic airport location info from airport database
|
||||||
bool fgFindAirportID( const string& id, FGAirport *a ) {
|
bool fgFindAirportID( const string& id, FGAirport *a ) {
|
||||||
|
|
|
@ -1323,7 +1323,7 @@ static void fgIdleFunction ( void ) {
|
||||||
// sleep(1);
|
// sleep(1);
|
||||||
idle_state = 1000;
|
idle_state = 1000;
|
||||||
|
|
||||||
cout << "Panel visible = " << fgPanelVisible() << endl;
|
SG_LOG( SG_GENERAL, SG_INFO, "Panel visible = " << fgPanelVisible() );
|
||||||
fgReshape( fgGetInt("/sim/startup/xsize"),
|
fgReshape( fgGetInt("/sim/startup/xsize"),
|
||||||
fgGetInt("/sim/startup/ysize") );
|
fgGetInt("/sim/startup/ysize") );
|
||||||
}
|
}
|
||||||
|
@ -1533,12 +1533,11 @@ int mainLoop( int argc, char **argv ) {
|
||||||
string base_version = fgBasePackageVersion();
|
string base_version = fgBasePackageVersion();
|
||||||
if ( !(base_version == required_version) ) {
|
if ( !(base_version == required_version) ) {
|
||||||
// tell the operator how to use this application
|
// tell the operator how to use this application
|
||||||
fgUsage();
|
|
||||||
|
|
||||||
cout << endl << "Base package check failed ... " \
|
cerr << endl << "Base package check failed ... " \
|
||||||
<< "Found version " << base_version << " at: " \
|
<< "Found version " << base_version << " at: " \
|
||||||
<< globals->get_fg_root() << endl;
|
<< globals->get_fg_root() << endl;
|
||||||
cout << "Please upgrade to version" << required_version << endl;
|
cerr << "Please upgrade to version" << required_version << endl;
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1551,26 +1550,6 @@ int mainLoop( int argc, char **argv ) {
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize the localization routines
|
|
||||||
if (globals->get_locale() == NULL) {
|
|
||||||
char *language = getenv("LANG");
|
|
||||||
if (language == NULL) {
|
|
||||||
SG_LOG(SG_GENERAL, SG_ALERT, "Unable to detect the language" );
|
|
||||||
language = "C";
|
|
||||||
}
|
|
||||||
|
|
||||||
SGPropertyNode *locale = fgInitLocale(language);
|
|
||||||
if (!locale) {
|
|
||||||
cerr
|
|
||||||
<< "Not internationalization settings specified in preferences.xml"
|
|
||||||
<< endl;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
globals->set_locale( locale );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize the Window/Graphics environment.
|
// Initialize the Window/Graphics environment.
|
||||||
if( !fgGlutInit(&argc, argv) ) {
|
if( !fgGlutInit(&argc, argv) ) {
|
||||||
SG_LOG( SG_GENERAL, SG_ALERT, "GLUT initialization failed ..." );
|
SG_LOG( SG_GENERAL, SG_ALERT, "GLUT initialization failed ..." );
|
||||||
|
|
|
@ -1164,6 +1164,8 @@ fgParseOptions (const string& path) {
|
||||||
void
|
void
|
||||||
fgUsage (bool verbose)
|
fgUsage (bool verbose)
|
||||||
{
|
{
|
||||||
|
SGPropertyNode *locale = globals->get_locale();
|
||||||
|
|
||||||
SGPropertyNode options_root;
|
SGPropertyNode options_root;
|
||||||
SGPath opath( globals->get_fg_root() );
|
SGPath opath( globals->get_fg_root() );
|
||||||
opath.append( "options.xml" );
|
opath.append( "options.xml" );
|
||||||
|
@ -1188,7 +1190,7 @@ fgUsage (bool verbose)
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
SGPropertyNode *usage = options->getNode("usage");
|
SGPropertyNode *usage = locale->getNode(options->getStringValue("usage"));
|
||||||
if (usage) {
|
if (usage) {
|
||||||
cout << "Usage: " << usage->getStringValue() << endl;
|
cout << "Usage: " << usage->getStringValue() << endl;
|
||||||
}
|
}
|
||||||
|
@ -1229,25 +1231,54 @@ fgUsage (bool verbose)
|
||||||
snprintf(cstr, 96, "\n --%s\n%32c", tmp.c_str(), ' ');
|
snprintf(cstr, 96, "\n --%s\n%32c", tmp.c_str(), ' ');
|
||||||
}
|
}
|
||||||
|
|
||||||
msg += cstr;
|
// There may be more than one <description> tag assosiated
|
||||||
SGPropertyNode *desc = option[k]->getNode("description");
|
// with one option
|
||||||
if (desc) {
|
|
||||||
msg += desc->getStringValue();
|
|
||||||
|
|
||||||
for ( unsigned int l = 1;
|
msg += cstr;
|
||||||
(desc = option[k]->getNode("description", l, false));
|
vector<SGPropertyNode_ptr>desc =
|
||||||
l++ )
|
option[k]->getChildren("description");
|
||||||
{
|
|
||||||
snprintf(cstr, 96, "\n%32c%s", ' ',
|
if (desc.size() > 0) {
|
||||||
desc->getStringValue());
|
for ( unsigned int l = 0; l < desc.size(); l++) {
|
||||||
msg += cstr;
|
|
||||||
}
|
// There may be more than one translation line.
|
||||||
msg += '\n';
|
|
||||||
}
|
string t = desc[l]->getStringValue();
|
||||||
|
SGPropertyNode *n = locale->getNode("strings");
|
||||||
|
vector<SGPropertyNode_ptr>trans_desc =
|
||||||
|
n->getChildren(t.substr(8).c_str());
|
||||||
|
|
||||||
|
for ( unsigned int m = 0; m < trans_desc.size(); m++ ) {
|
||||||
|
string t_str = trans_desc[m]->getStringValue();
|
||||||
|
|
||||||
|
if ((m > 0) || ((l > 0) && m == 0)) {
|
||||||
|
snprintf(cstr, 96, "%32c", ' ');
|
||||||
|
msg += cstr;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the string is too large to fit on the screen,
|
||||||
|
// then split it up in several pieces.
|
||||||
|
|
||||||
|
while ( t_str.size() > 47 ) {
|
||||||
|
|
||||||
|
unsigned int m = t_str.rfind(' ', 47);
|
||||||
|
msg += t_str.substr(0, m);
|
||||||
|
snprintf(cstr, 96, "\n%32c", ' ');
|
||||||
|
msg += cstr;
|
||||||
|
|
||||||
|
t_str.erase(t_str.begin(), t_str.begin() + m + 1);
|
||||||
|
}
|
||||||
|
msg += t_str + '\n';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SGPropertyNode *name = section[j]->getNode("name");
|
SGPropertyNode *name =
|
||||||
|
locale->getNode(section[j]->getStringValue("name"));
|
||||||
|
|
||||||
if (!msg.empty() && name) {
|
if (!msg.empty() && name) {
|
||||||
cout << endl << name->getStringValue() << ":" << endl;
|
cout << endl << name->getStringValue() << ":" << endl;
|
||||||
cout << msg;
|
cout << msg;
|
||||||
|
|
|
@ -160,10 +160,16 @@ static int gen_vasi_light_map() {
|
||||||
|
|
||||||
// top half white, bottom half red
|
// top half white, bottom half red
|
||||||
env_map[i][j][0] = 255;
|
env_map[i][j][0] = 255;
|
||||||
if ( i >= half_res ) {
|
if ( i > half_res ) {
|
||||||
|
// white
|
||||||
env_map[i][j][1] = 255;
|
env_map[i][j][1] = 255;
|
||||||
env_map[i][j][2] = 255;
|
env_map[i][j][2] = 255;
|
||||||
|
} else if ( i == half_res - 1 || i == half_res ) {
|
||||||
|
// pink
|
||||||
|
env_map[i][j][1] = 127;
|
||||||
|
env_map[i][j][2] = 127;
|
||||||
} else {
|
} else {
|
||||||
|
// red
|
||||||
env_map[i][j][1] = 0;
|
env_map[i][j][1] = 0;
|
||||||
env_map[i][j][2] = 0;
|
env_map[i][j][2] = 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue