Salome HOME
Translate strings with corresponded codec
[modules/shaper.git] / src / Config / Config_Translator.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
2
3 // File:        Config_Translator.cpp
4 // Created:     31 May 2016
5 // Author:      Vitaly SMETANNIKOV
6
7 #include "Config_Translator.h"
8 #include "Config_XMLReader.h"
9 #include "Config_Common.h"
10
11 #include <fstream>
12 #include <ostream>
13
14 class Config_TSReader : public Config_XMLReader
15 {
16 public:
17   Config_TSReader(const std::string& theTSFile) : Config_XMLReader(theTSFile) {}
18
19   const Config_Translator::Translator& translator() const { return myTranslator; }
20   const Config_Translator::Dictionary& codecs() const { return myCodecs; }
21
22 protected:
23   /// Overloaded method. Defines how to process each node
24   virtual void processNode(xmlNodePtr theNode);
25 private:
26   Config_Translator::Translator myTranslator;
27   Config_Translator::Dictionary myCodecs;
28 };
29
30 void Config_TSReader::processNode(xmlNodePtr theNode)
31 {
32   static std::string aName;
33   static std::string aSource;
34   std::string aTranslat;
35
36   if (isNode(theNode, "context", NULL)) {
37     aName = "";
38   } else if (isNode(theNode, "name", NULL)) {
39     aName = getContent(theNode);
40     myCodecs[aName] = encoding();
41   } else if (isNode(theNode, "message", NULL)) {
42     aSource = "";
43   } else if (isNode(theNode, "source", NULL)) {
44     aSource = getContent(theNode);
45   } else if (isNode(theNode, "translation", NULL)) {
46     aTranslat = getContent(theNode);
47     if ((aName.size() > 0) && (aSource.size() > 0))
48       myTranslator[aName][aSource] = aTranslat;
49   }
50 }
51
52 //******************************************************************************
53 //******************************************************************************
54 //******************************************************************************
55 Config_Translator::Translator Config_Translator::myTranslator;
56 Config_Translator::Dictionary Config_Translator::myCodecs;
57
58 #ifdef _DEBUG
59 #ifdef MISSED_TRANSLATION
60 Config_Translator::Translator Config_Translator::myMissed;
61 #endif
62 #endif
63
64 bool Config_Translator::load(const std::string& theFileName)
65 {
66   Config_TSReader aReader(theFileName);
67   aReader.readAll();
68
69   const Translator& aTranslator = aReader.translator();
70   Translator::const_iterator aIt;
71   std::string aContext;
72   Dictionary aDictionary;
73   for (aIt = aTranslator.cbegin(); aIt != aTranslator.cend(); aIt++) {
74     aContext = (*aIt).first;
75     aDictionary = (*aIt).second;
76     if (myTranslator.count(aContext) == 0) {
77       myTranslator[aContext] = aDictionary;
78     } else {
79       Dictionary::const_iterator aDictIt;
80       for (aDictIt = aDictionary.cbegin(); aDictIt != aDictionary.cend(); aDictIt++) {
81         myTranslator[aContext][(*aDictIt).first] = (*aDictIt).second;
82       }
83     }
84   }
85
86   const Dictionary aCodecs = aReader.codecs();
87   Dictionary::const_iterator aDictIt;
88   for (aDictIt = aCodecs.cbegin(); aDictIt != aCodecs.cend(); aDictIt++) {
89     myCodecs[aDictIt->first] = aDictIt->second;
90   }
91   return true;
92 }
93
94 std::string Config_Translator::translate(std::shared_ptr<Events_InfoMessage> theInfo)
95 {
96   std::string aContext = theInfo->context();
97   std::string aMessage = theInfo->message();
98   std::list<std::string> aParameters = theInfo->parameters();
99   return translate(aContext, aMessage, aParameters);
100 }
101
102
103 std::string insertParameters(const std::string& theString, const std::list<std::string>& theParams)
104 {
105   std::string aResult = theString;
106   std::list<std::string>::const_iterator aIt;
107   int i;
108   char aBuf[20];
109   std::string aParam;
110   for (i=1, aIt = theParams.cbegin(); aIt != theParams.cend(); aIt++, i++) {
111     aParam = (*aIt);
112     sprintf_s(aBuf, "%d", i);
113     std::string aCode = std::string("%") + std::string(aBuf);
114     size_t aPos = aResult.find(aCode);
115     if (aPos != std::string::npos) {
116       std::string aFirst = aResult.substr(0, aPos);
117       std::string aLast = aResult.substr(aPos + aCode.length(), std::string::npos);
118       aResult = aFirst + aParam + aLast;
119     }
120   }
121   return aResult;
122 }
123
124 std::string Config_Translator::translate(const std::string& theContext,
125                                          const std::string& theMessage, 
126                                          const std::list<std::string>& theParams)
127 {
128   if (myTranslator.count(theContext) > 0) {
129     if (myTranslator[theContext].count(theMessage) > 0) {
130       std::string aTranslation = myTranslator[theContext][theMessage];
131       if (theParams.size() > 0) {
132         aTranslation = insertParameters(aTranslation, theParams);
133       }
134       return aTranslation;
135     }
136   }
137   std::string aMsg = theMessage;
138   if (theParams.size() > 0) {
139     aMsg = insertParameters(aMsg, theParams);
140   }
141 #ifdef _DEBUG
142 #ifdef MISSED_TRANSLATION
143   myMissed[theContext][theMessage] = "";
144 #endif
145 #endif
146   return aMsg;
147 }
148
149
150 std::string Config_Translator::codec(const std::string& theContext)
151
152   return (myCodecs.count(theContext) > 0)? myCodecs[theContext] : "UTF-8"; 
153 }
154
155
156 #ifdef _DEBUG
157 #ifdef MISSED_TRANSLATION
158 void Config_Translator::saveMissedTranslations()
159 {
160   if (myMissed.size() == 0)
161     return;
162
163   char* aPath = getenv("ROOT_DIR");
164 #ifdef WIN32
165   std::string aFile = aPath + std::string("\\MissedTranslation.ts");
166 #else
167   std::string aFile = aPath + std::string("/MissedTranslation.ts");
168 #endif
169   std::ofstream oFStream;
170
171   // Delete old file
172   int aa = remove(aFile.c_str());
173
174   oFStream.open(aFile, std::ofstream::out | std::ofstream::app);
175   if (oFStream.is_open()) {
176     Translator::const_iterator aContIt;
177     Dictionary::const_iterator aDictIt;
178     std::string aContext;
179     std::string aSrc;
180     Dictionary aDict;
181
182     oFStream << "<TS version=\"2.0\">" << std::endl;
183     for(aContIt = myMissed.cbegin(); aContIt != myMissed.cend(); aContIt++) {
184       oFStream << "<context>" << std::endl;
185
186       aContext = aContIt->first;
187       oFStream << "  <name>" << aContext << "</name>" << std::endl;
188
189       aDict = aContIt->second;
190       for(aDictIt = aDict.cbegin(); aDictIt != aDict.cend(); aDictIt++) {
191         oFStream << "  <message>" << std::endl;
192         aSrc = aDictIt->first;
193
194         oFStream << "    <source>" << aSrc << "</source>" << std::endl;
195         oFStream << "    <translation>" << "</translation>" << std::endl;
196
197         oFStream << "  </message>" << std::endl;
198       }
199       oFStream << "</context>" << std::endl;
200     }
201
202     oFStream << "</TS>" << std::endl;
203     oFStream.close();
204   }
205 }
206 #endif
207 #endif