Commit 1baa890f authored by claes's avatar claes

New language design with textfile and binary tree

parent 8e9d0172
...@@ -8,211 +8,275 @@ extern "C" { ...@@ -8,211 +8,275 @@ extern "C" {
#include "co_lng.h" #include "co_lng.h"
lng_eLanguage Lng::lang = lng_eLanguage_en_us; lng_eLanguage Lng::lang = lng_eLanguage_en_us;
tree_sTable *Lng::tree = 0;
char Lng::items[][2][40] = { char *Lng::get_language_str()
{"Help", "Hjlp"}, {
{"Help Class", "Hjlp Klass"}, return lang_to_str( lang);
{"Graph", "Bild"}, }
{"Trend", "Trend"},
{"Open Object", "ppna Objekt"},
{"Open Object...", "ppna Objekt"},
{"RtNavigator", "RtNavigatr"},
{"Object Graph", "Objekt Bild"},
{"Crossreferences", "Korsreferenser"},
{"DataSheet", "Datablad"},
{"Collect", "Samla"},
{"Type Graph...","Typ Bild..."},
{"Open Plc...", "ppna Plc..."},
{"Open Plc", "ppna Plc"},
{"Note", "Notera"},
{"Photo", "Foto"},
{"Fast", "Snabbkurva"},
{"Trend", "Trendkurva"},
{"CircuitDiagram", "KopplingsSchema"},
{"Block Events...", "Blockera Hndelser..."},
{"Hist Event...", "Historisk lista..."},
{"Alarm List", "Larmlista"},
{"Event List", "Hndelselista"},
{"Historical List", "Historisk lista"},
{"Link", "Lnkar"},
{"Subscription Client", "Prenumerationer Klient"},
{"Subscription Server", "Prenumerationer Server"},
{"Nethandler", "Nthanterare"},
{"Communication", "Kommunikation"},
{"Device", "Enheter"},
{"PlcThread", "PlcTrdar"},
{"PlcPgm", "PlcPgm"},
{"Logging", "Loggning"},
{"Logging entry 1", "Loggning entry 1"},
{"Logging entry 2", "Loggning entry 2"},
{"Logging entry 3", "Loggning entry 3"},
{"Logging entry 4", "Loggning entry 4"},
{"Logging entry 5", "Loggning entry 5"},
{"Logging entry 6", "Loggning entry 6"},
{"Logging entry 7", "Loggning entry 7"},
{"Logging entry 8", "Loggning entry 8"},
{"Logging entry 9", "Loggning entry 9"},
{"Logging entry 10", "Loggning entry 10"},
{"System Messages", "System Meddelanden"},
{"Volume", "Volym"},
{"Volumes", "Volymer"},
{"Nodes", "Noder"},
{"Database", "Databas"},
{"Alarm", "Larm"},
{"Store", "Lagra"},
{"System", "System"},
{"Exit", "Avsluta"},
{"Close", "Stng"},
{"Active", "Aktiv"},
{"Insert", "LggIn"},
{"Start", "Starta"},
{"Stop", "Stoppa"},
{"Restore", "terskapa"},
{"ShowFile", "VisaFil"},
{"Time (ms)", "Tid (ms)"},
{"File", "Fil"},
{"Type", "Typ"},
{"BufferSize", "BufferStorlek"},
{"FullBufferStop","FullBufferStopp"},
{"ShortName", "KortNamn"},
{"Parameter", "Parameter"},
{"ConditionParameter", "VillkorsParameter"},
{"value >", "vrde >"},
{"Description", "Beskrivning"},
{"InitialValue", "InitialVrde"},
{"ActualValue", "NuVrde"},
{"Unit", "Enhet"},
{"Channel", "Kanal"},
{"Hold", "Hll"},
{"Slider", "Reglage"},
{"FilterType", "FilterTyp"},
{"Value", "Vrde"},
{"Identity", "Identitet"},
{"Number", "Nummer"},
{"Range", "Omrde"},
{"SensorSignalValue", "GivarSignalVrde"},
{"ChannelSignalValue", "KanalSignalVrde"},
{"RawValue", "RVrde"},
{"Update range", "Uppdatera omrde"},
{"Signal", "Signal"},
{"TestOn", "TestTill"},
{"TestValue", "TestVrde"},
{"Mode", "Mod"},
{"Man", "Man"},
{"Auto", "Auto"},
{"Cascade", "Kaskad"},
{"Local", "Lokal"},
{"Extern SetValue", "Externt BrVrde"},
{"Force", "Tvinga"},
{"Set value", "Br vrde"},
{"Process value","r vrde"},
{"Out value", "Ut signal"},
{"Blocked Alarms", "Blockerade larm"},
{"Alarm Blocking", "Larmblockering"},
{"Contents", "Innehll"},
{"page", "sidan"},
{"See", "Se"},
{"Class", "Klass"},
{"Author", "Redaktr"},
{"Version", "Version"},
{"Code", "Kod"},
{"Body", "Kropp"},
{"Type", "Typ"},
{"English text not available", "Svensk text finns ej tillgnglig"},
{"Object Reference Manual", "Objekt handbok"},
{"Components", "Komponenter"},
{"Signals", "Signaler"},
{"Methods", "Metoder"},
{"On", "Till"},
{"Off", "Frn"},
{"Tripped", "Utlst"},
{"Temperature", "Temperatur"},
{"Limits", "Grnser"},
{"HighHigh", "HgHg"},
{"High", "Hg"},
{"Low", "Lg"},
{"LowLow", "LgLg"},
{"Used", "Anvnd"},
{"Limit", "Grns"},
{"Hysteresis", "Hysteres"},
{"Delay", "Frdrjning"},
{"Switch open", "Grnslge ppen"},
{"Switch closed", "Grnslge stngd"},
{"Error detected", "Fel detekterat"},
{"Overload", "verlast"},
{"Safety switch", "Skerhetsbrytare"},
{"Ready", "Klar"},
{"Extern interlock","Extern frregling"},
{"Contactor", "Kontaktor"},
{"Circuit breaker","Effektbrytare"},
{"Startlock", "Startsprr"},
{"Frequency converter","Frekvensomriktare"},
};
lng_eLanguage Lng::str_to_lang( char *str)
{
if ( strcmp( str, "en_us") == 0)
return lng_eLanguage_en_us;
if ( strcmp( str, "sv_se") == 0)
return lng_eLanguage_sv_se;
if ( strcmp( str, "ru_ru") == 0)
return lng_eLanguage_ru_ru;
char *Lng::get_language_str() return lng_eLanguage_;
}
char *Lng::lang_to_str( lng_eLanguage language)
{ {
static char result[20]; static char result[20];
switch( lang) { switch( language) {
case lng_eLanguage_sv_se: case lng_eLanguage_sv_se:
strcpy( result, "sv_se"); strcpy( result, "sv_se");
break; break;
case lng_eLanguage_ru_ru:
strcpy( result, "ru_ru");
break;
default: default:
strcpy( result, "en_us"); strcpy( result, "en_us");
} }
return result; return result;
} }
char *Lng::translate( char *str) static int compKey( tree_sTable *tp, tree_sNode *x, tree_sNode *y)
{
lang_sKey *xKey = (lang_sKey *) (tp->keyOffset + (char *) x);
lang_sKey *yKey = (lang_sKey *) (tp->keyOffset + (char *) y);
char type = (xKey->type == 0) ? yKey->type : xKey->type;
switch ( type) {
case 'E':
return strcmp(xKey->text, yKey->text);
case 'B': {
char *s = strrchr( xKey->text, ',');
if ( s)
return strncmp(xKey->text, yKey->text,
(unsigned int)s - (unsigned int)xKey->text);
return strcmp(xKey->text, yKey->text);
}
}
return 0;
}
char *Lng::translate( char *text)
{ {
static char result[200]; static char result[200];
lang_sKey key;
lang_sRecord *record;
int sts;
char *in_p; char *in_p;
if ( lang == lng_eLanguage_en_us) { if ( lang == lng_eLanguage_en_us || tree == 0) {
// No translation is needed // No translation is needed
strcpy( result, str); strncpy( result, text, sizeof(result));
result[sizeof(result)-1] = 0;
return result; return result;
} }
// Remove space // Remove space
for ( in_p = str; *in_p == ' ' && *in_p; in_p++) for ( in_p = text; *in_p == ' ' && *in_p; in_p++)
; ;
for ( int i = 0; i < (int) (sizeof(items)/sizeof(items[0])); i++) { strcpy( key.text, text);
if ( strcmp( items[i][0], in_p) == 0) { key.type = 0;
strcpy( result, items[i][lang]); record = (lang_sRecord *) tree_Find( &sts, tree, &key);
return result; if ( ODD(sts)) {
switch ( record->key.type) {
case 'B': {
char *s = strrchr( record->transl, ',');
if ( s) {
char *t = strrchr( text, ',');
if ( t) {
strncpy( result, record->transl,
(unsigned int)s - (unsigned int)record->transl + 1);
strcat( result, t+1);
} }
else
strcpy( result, record->transl);
}
else
strcpy( result, record->transl);
break;
}
default:
strcpy( result, record->transl);
}
}
else {
strncpy( result, text, sizeof(result));
result[sizeof(result)-1] = 0;
} }
// Not found
strcpy( result, str);
return result; return result;
} }
int Lng::translate( char *in, char *out) int Lng::translate( char *text, char *out)
{ {
char result[200];
lang_sKey key;
lang_sRecord *record;
int sts;
char *in_p; char *in_p;
if ( lang == lng_eLanguage_en_us) { if ( lang == lng_eLanguage_en_us || tree == 0) {
// No translation is needed // No translation is needed
return 0; return 0;
} }
// Remove space // Remove space
for ( in_p = in; *in_p == ' ' && *in_p; in_p++) for ( in_p = text; *in_p == ' ' && *in_p; in_p++)
; ;
for ( int i = 0; i < (int) (sizeof(items)/sizeof(items[0])); i++) { strcpy( key.text, text);
if ( strcmp( items[i][0], in_p) == 0) { key.type = 0;
strcpy( out, items[i][lang]); record = (lang_sRecord *) tree_Find( &sts, tree, &key);
return 1; if ( ODD(sts)) {
switch ( record->key.type) {
case 'B': {
char *s = strrchr( record->transl, ',');
if ( s) {
char *t = strrchr( text, ',');
if ( t) {
strncpy( result, record->transl,
(unsigned int)s - (unsigned int)record->transl + 1);
strcat( result, t+1);
}
else
strcpy( result, record->transl);
}
else
strcpy( result, record->transl);
break;
}
default:
strcpy( result, record->transl);
} }
strcpy( out, result);
return 1;
} }
// Not found // Not found
return 0; return 0;
} }
void Lng::unload()
{
int sts;
tree_DeleteTable( &sts, tree);
tree = 0;
}
bool Lng::read()
{
char fname1[120] = "$pwr_exe/en_us/lang_en_us.dat";
char fname2[120] = "$pwr_exe/%s/lang_%s.dat";
pwr_tFileName filename1, filename2;
int sts;
sprintf( filename2, fname2, get_language_str(), get_language_str());
dcli_translate_filename( filename1, fname1);
dcli_translate_filename( filename2, filename2);
ifstream fp1( filename1);
if ( !fp1)
return false;
ifstream fp2( filename2);
if ( !fp2)
return false;
if ( tree)
tree_DeleteTable( &sts, tree);
tree = tree_CreateTable( &sts, sizeof(lang_sKey), offsetof(lang_sRecord, key),
sizeof(lang_sRecord), 100, compKey);
Row r1( fp1, fname1);
Row r2( fp2, fname2);
bool hit = true;
for (;;) {
if ( hit) {
if ( !read_line( r1))
break;
if ( !read_line( r2))
break;
}
else if ( r1.lt( r2)) {
if ( !read_line( r1))
break;
}
else {
if ( !read_line( r2))
break;
}
hit = false;
if ( r1.eq( r2))
hit = true;
if ( hit) {
lang_sKey key;
lang_sRecord *record;
strcpy( key.text, r1.text);
key.type = r1.type;
record = (lang_sRecord *) tree_Insert( &sts, tree, &key);
strcpy( record->transl, r2.text);
// printf ( "%c %d.%d.%d '%s' '%s'\n", r1.type, r1.n1, r1.n2, r1.n3, r1.text,r2.text);
}
}
return true;
}
bool Lng::read_line( Row& r)
{
int nr;
char line[200];
char *s, *t;
for(;;) {
if ( !r.fp.getline( line, sizeof( line)))
return false;
r.row++;
if ( line[0] == '#' || line[0] == 0)
continue;
nr = sscanf( line, "%c%d.%d.%d", &r.type, &r.n1, &r.n2, &r.n3);
if ( nr != 4) {
printf( "Error in line %d, file %s\n", r.row, r.fname);
continue;
}
bool in_text = false;
for ( s = line, t = r.text; *s; s++) {
if ( in_text) {
if ( *s == '\"') {
if ( *(s-1) == '\\')
*(t-1) = '\"';
else
break;
}
else
*t++ = *s;;
}
if ( !in_text && *s == '\"')
in_text = 1;
}
*t = 0;
break;
}
return true;
}
void Lng::get_uid( char *in, char *out) void Lng::get_uid( char *in, char *out)
{ {
char result[200]; char result[200];
...@@ -236,6 +300,24 @@ void Lng::get_uid( char *in, char *out) ...@@ -236,6 +300,24 @@ void Lng::get_uid( char *in, char *out)
strcpy( out, result); strcpy( out, result);
} }
void Lng::set( char *language)
{
lng_eLanguage l = str_to_lang( language);
if ( l != lng_eLanguage_)
set( l);
}
void Lng::set( lng_eLanguage language)
{
if ( lang == language)
return;
lang = language;
if ( lang == lng_eLanguage_en_us)
unload();
else
read();
}
......
...@@ -8,6 +8,9 @@ ...@@ -8,6 +8,9 @@
<Description>. */ <Description>. */
#include <iostream.h>
#include <fstream.h>
#if defined __cplusplus #if defined __cplusplus
extern "C" { extern "C" {
#endif #endif
...@@ -16,11 +19,70 @@ extern "C" { ...@@ -16,11 +19,70 @@ extern "C" {
# include "pwr.h" # include "pwr.h"
#endif #endif
#ifndef co_tree_h
# include "co_tree.h"
#endif
typedef enum { typedef enum {
lng_eLanguage_en_us = 0, lng_eLanguage_,
lng_eLanguage_sv_se = 1 lng_eLanguage_en_us,
lng_eLanguage_sv_se,
lng_eLanguage_ru_ru
} lng_eLanguage; } lng_eLanguage;
typedef struct {
char text[80];
char type;
} lang_sKey;
typedef struct {
tree_sNode n;
lang_sKey key;
char transl[80];
} lang_sRecord;
class Row {
public:
char type;
int n1;
int n2;
int n3;
char text[200];
int row;
ifstream& fp;
char fname[200];
Row( ifstream& f, char *filename) : row(0), fp(f) {
strcpy( text, ""); strcpy( fname, filename);}
bool eq( Row& r) { return n1 == r.n1 && n2 == r.n2 && n3 == r.n3;}
bool lt( Row& r) {
if ( n1 < r.n1)
return true;
else if ( n1 > r.n1)
return false;
if ( n2 < r.n2)
return true;
else if ( n2 > r.n2)
return false;
if ( n3 < r.n3)
return true;
return false;
}
bool gt( Row& r) {
if ( n1 > r.n1)
return true;
else if ( n1 < r.n1)
return false;
if ( n2 > r.n2)
return true;
else if ( n2 < r.n2)
return false;
if ( n3 > r.n3)
return true;
return false;
}
};
class Lng { class Lng {
public: public:
Lng() {}; Lng() {};
...@@ -41,19 +103,24 @@ class Lng { ...@@ -41,19 +103,24 @@ class Lng {
static const int Open_Plc___ = 13; static const int Open_Plc___ = 13;
static char items[][2][40]; static char items[][2][40];
static void set( lng_eLanguage language) { lang = language;}; static tree_sTable *tree;
static bool read();
static bool read_line( Row& r);
static char *translate( char *text);
static char *get_language_str();
static int translate( char *in, char *out);
static void unload();
static void set( lng_eLanguage language);
static lng_eLanguage current() { return lang;} static lng_eLanguage current() { return lang;}
static void set( char *language) static void set( char *language);
{ if ( strcmp(language,"en_us") == 0) lang = lng_eLanguage_en_us;
else if ( strcmp(language,"sv_se") == 0) lang = lng_eLanguage_sv_se;};
static char *get( int item) static char *get( int item)
{ return items[lang][item];}; { return items[lang][item];}
static char *get( lng_eLanguage language, int item) static char *get( lng_eLanguage language, int item)
{ return items[language][item];}; { return items[language][item];}
static char *translate( char *str);
static int translate( char *in, char *out);
static char *get_language_str();
static void get_uid( char *in, char *out); static void get_uid( char *in, char *out);
static lng_eLanguage str_to_lang( char *str);
static char *lang_to_str( lng_eLanguage language);
}; };
#if defined __cplusplus #if defined __cplusplus
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment