Browse Source

Merge pull request #262 from Deledrius/plString_pfLocalizationMgr

plStringification of pfLocalizationMgr
Adam Johnson 12 years ago
parent
commit
dbf23ac28a
  1. 2
      Sources/Plasma/FeatureLib/pfGameGUIMgr/pfGUITextBoxMod.cpp
  2. 456
      Sources/Plasma/FeatureLib/pfLocalizationMgr/pfLocalizationDataMgr.cpp
  3. 76
      Sources/Plasma/FeatureLib/pfLocalizationMgr/pfLocalizationDataMgr.h
  4. 8
      Sources/Plasma/FeatureLib/pfLocalizationMgr/pfLocalizationMgr.cpp
  5. 6
      Sources/Plasma/FeatureLib/pfLocalizationMgr/pfLocalizationMgr.h
  6. 300
      Sources/Plasma/FeatureLib/pfLocalizationMgr/pfLocalizedString.cpp
  7. 36
      Sources/Plasma/FeatureLib/pfLocalizationMgr/pfLocalizedString.h
  8. 4
      Sources/Plasma/FeatureLib/pfPython/cyMisc.cpp
  9. 2
      Sources/Plasma/FeatureLib/pfPython/cyMisc.h
  10. 49
      Sources/Plasma/FeatureLib/pfPython/cyMiscGlue.cpp
  11. 12
      Sources/Tools/MaxComponent/plPickLocalizationDlg.cpp
  12. 2
      Sources/Tools/MaxMain/GlobalUtility.cpp
  13. 52
      Sources/Tools/plLocalizationEditor/plAddDlgs.cpp
  14. 14
      Sources/Tools/plLocalizationEditor/plAddDlgs.h
  15. 130
      Sources/Tools/plLocalizationEditor/plEditDlg.cpp
  16. 7
      Sources/Tools/plLocalizationEditor/plEditDlg.h
  17. 52
      Sources/Tools/plLocalizationEditor/plLocTreeView.cpp
  18. 8
      Sources/Tools/plLocalizationEditor/plLocTreeView.h
  19. 4
      Sources/Tools/plLocalizationEditor/plLocalizationEditor.cpp

2
Sources/Plasma/FeatureLib/pfGameGUIMgr/pfGUITextBoxMod.cpp

@ -121,7 +121,7 @@ void pfGUITextBoxMod::IUpdate( void )
std::wstring drawStr; std::wstring drawStr;
if (fUseLocalizationPath && !fLocalizationPath.IsEmpty() && pfLocalizationMgr::InstanceValid()) if (fUseLocalizationPath && !fLocalizationPath.IsEmpty() && pfLocalizationMgr::InstanceValid())
drawStr = pfLocalizationMgr::Instance().GetString(fLocalizationPath.ToWchar().GetData()); drawStr = pfLocalizationMgr::Instance().GetString(fLocalizationPath).ToWchar().GetData();
else else
{ {
if( fText != nil ) if( fText != nil )

456
Sources/Plasma/FeatureLib/pfLocalizationMgr/pfLocalizationDataMgr.cpp

File diff suppressed because it is too large Load Diff

76
Sources/Plasma/FeatureLib/pfLocalizationMgr/pfLocalizationDataMgr.h

@ -55,6 +55,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
#include "pfLocalizedString.h" #include "pfLocalizedString.h"
class plStatusLog; class plStatusLog;
class plString;
// Helper classes/structs that are only used in this main class // Helper classes/structs that are only used in this main class
class LocalizationDatabase; class LocalizationDatabase;
@ -81,49 +82,48 @@ protected:
{ {
protected: protected:
// Outer map is Age, then Set, finally Name // Outer map is Age, then Set, finally Name
typedef std::map<std::wstring, std::map<std::wstring, std::map<std::wstring, mapT> > > ThreePartMap; typedef std::map<plString, std::map<plString, std::map<plString, mapT> > > ThreePartMap;
ThreePartMap fData; ThreePartMap fData;
void ISplitString(std::wstring key, std::wstring &age, std::wstring &set, std::wstring &name); void ISplitString(plString key, plString &age, plString &set, plString &name);
public: public:
// We will just have very basic functionality // We will just have very basic functionality
bool exists(const std::wstring & key); // returns true if the key exists bool exists(const plString & key); // returns true if the key exists
bool setExists(const std::wstring & key); // returns true if the age.set exists (ignores name if passed in) bool setExists(const plString & key); // returns true if the age.set exists (ignores name if passed in)
void erase(const std::wstring & key); // erases the key from the map void erase(const plString & key); // erases the key from the map
mapT &operator[](const std::wstring &key); // returns the item referenced by the key (and creates if necessary) mapT &operator[](const plString &key); // returns the item referenced by the key (and creates if necessary)
WStringVector getAgeList(); // returns a list of all ages in this map std::vector<plString> getAgeList(); // returns a list of all ages in this map
WStringVector getSetList(const std::wstring & age); // returns a list of all sets in the specified age std::vector<plString> getSetList(const plString & age); // returns a list of all sets in the specified age
WStringVector getNameList(const std::wstring & age, const std::wstring & set); std::vector<plString> getNameList(const plString & age, const plString & set);
}; };
LocalizationDatabase *fDatabase; LocalizationDatabase *fDatabase;
typedef std::map<std::wstring, pfLocalizedString> localizedElement; typedef std::map<plString, pfLocalizedString> localizedElement;
// Contains all localized strings, the key is the Age.Set.Name specified by XML, in localizedElement, the key is the language string // Contains all localized strings, the key is the Age.Set.Name specified by XML, in localizedElement, the key is the language string
pf3PartMap<localizedElement> fLocalizedElements; pf3PartMap<localizedElement> fLocalizedElements;
std::string fDataPath; plString fDataPath;
localizedElement ICreateLocalizedElement(); // ease of use function that creates a basic localized element object localizedElement ICreateLocalizedElement(); // ease of use function that creates a basic localized element object
std::wstring IGetCurrentLanguageName(); // get the name of the current language plString IGetCurrentLanguageName(); // get the name of the current language
WStringVector IGetAllLanguageNames(); std::vector<plString> IGetAllLanguageNames();
void IConvertElement(LocElementInfo *elementInfo, const std::wstring & curPath); void IConvertElement(LocElementInfo *elementInfo, const plString & curPath);
void IConvertSet(LocSetInfo *setInfo, const std::wstring & curPath); void IConvertSet(LocSetInfo *setInfo, const plString & curPath);
void IConvertAge(LocAgeInfo *ageInfo, const std::wstring & curPath); void IConvertAge(LocAgeInfo *ageInfo, const plString & curPath);
char *IConvertToByteStream(const std::wstring & data, uint32_t &len); // converts the wstring data to a string of bytes for file writing void IWriteText(const plString & filename, const plString & ageName, const plString & languageName); // Write localization text to the specified file
void IWriteText(const std::string & filename, const std::wstring & ageName, const std::wstring & languageName); // Write localization text to the specified file
pfLocalizationDataMgr(const std::string & path); pfLocalizationDataMgr(const plString & path);
public: public:
virtual ~pfLocalizationDataMgr(); virtual ~pfLocalizationDataMgr();
static void Initialize(const std::string & path); static void Initialize(const plString & path);
static void Shutdown(); static void Shutdown();
static pfLocalizationDataMgr &Instance(void) {return *fInstance;} static pfLocalizationDataMgr &Instance(void) {return *fInstance;}
static bool InstanceValid(void) {return fInstance != nil;} static bool InstanceValid(void) {return fInstance != nil;}
@ -131,32 +131,38 @@ public:
void SetupData(); void SetupData();
pfLocalizedString GetElement(const std::wstring & name); pfLocalizedString GetElement(const plString & name);
pfLocalizedString GetSpecificElement(const std::wstring & name, const std::wstring & languageName); pfLocalizedString GetSpecificElement(const plString & name, const plString & languageName);
WStringVector GetAgeList() { return fLocalizedElements.getAgeList(); } std::vector<plString> GetAgeList()
WStringVector GetSetList(const std::wstring & ageName) { return fLocalizedElements.getSetList(ageName); } {
WStringVector GetElementList(const std::wstring & ageName, const std::wstring & setName) return fLocalizedElements.getAgeList();
}
std::vector<plString> GetSetList(const plString & ageName)
{
return fLocalizedElements.getSetList(ageName);
}
std::vector<plString> GetElementList(const plString & ageName, const plString & setName)
{ {
return fLocalizedElements.getNameList(ageName, setName); return fLocalizedElements.getNameList(ageName, setName);
} }
WStringVector GetLanguages(const std::wstring & ageName, const std::wstring & setName, const std::wstring & elementName); std::vector<plString> GetLanguages(const plString & ageName, const plString & setName, const plString & elementName);
std::wstring GetElementXMLData(const std::wstring & name, const std::wstring & languageName); plString GetElementXMLData(const plString & name, const plString & languageName);
std::wstring GetElementPlainTextData(const std::wstring & name, const std::wstring & languageName); plString GetElementPlainTextData(const plString & name, const plString & languageName);
// These convert the XML data to the actual subtitle and return true if successful (editor only) // These convert the XML data to the actual subtitle and return true if successful (editor only)
bool SetElementXMLData(const std::wstring & name, const std::wstring & languageName, const std::wstring & xmlData); bool SetElementXMLData(const plString & name, const plString & languageName, const plString & xmlData);
bool SetElementPlainTextData(const std::wstring & name, const std::wstring & languageName, const std::wstring & plainText); bool SetElementPlainTextData(const plString & name, const plString & languageName, const plString & plainText);
// Addition and deletion functions, return true if successful (editor only) // Addition and deletion functions, return true if successful (editor only)
bool AddLocalization(const std::wstring & name, const std::wstring & newLanguage); bool AddLocalization(const plString & name, const plString & newLanguage);
bool AddElement(const std::wstring & name); bool AddElement(const plString & name);
bool DeleteLocalization(const std::wstring & name, const std::wstring & languageName); bool DeleteLocalization(const plString & name, const plString & languageName);
bool DeleteElement(const std::wstring & name); bool DeleteElement(const plString & name);
// Writes the current database to the disk (editor only). It will create all the files and put them into path // Writes the current database to the disk (editor only). It will create all the files and put them into path
void WriteDatabaseToDisk(const std::string & path); void WriteDatabaseToDisk(const plString & path);
void OutputTreeToLog(); // prints the localization tree to the log file void OutputTreeToLog(); // prints the localization tree to the log file
}; };

8
Sources/Plasma/FeatureLib/pfLocalizationMgr/pfLocalizationMgr.cpp

@ -73,7 +73,7 @@ pfLocalizationMgr::~pfLocalizationMgr()
//// Initialize ////////////////////////////////////////////////////// //// Initialize //////////////////////////////////////////////////////
void pfLocalizationMgr::Initialize(const std::string & dataPath) void pfLocalizationMgr::Initialize(const plString & dataPath)
{ {
if (fInstance) if (fInstance)
return; return;
@ -95,13 +95,13 @@ void pfLocalizationMgr::Shutdown()
//// GetString /////////////////////////////////////////////////////// //// GetString ///////////////////////////////////////////////////////
std::wstring pfLocalizationMgr::GetString(const std::wstring & path, const std::vector<std::wstring> & args) plString pfLocalizationMgr::GetString(const plString & path, const std::vector<plString> & args)
{ {
return pfLocalizationDataMgr::Instance().GetElement(path) % args; return pfLocalizationDataMgr::Instance().GetElement(path) % args;
} }
std::wstring pfLocalizationMgr::GetString(const std::wstring & path) plString pfLocalizationMgr::GetString(const plString & path)
{ {
std::vector<std::wstring> args; // blank args so that % signs are still handled correctly std::vector<plString> args; // blank args so that % signs are still handled correctly
return pfLocalizationDataMgr::Instance().GetElement(path) % args; return pfLocalizationDataMgr::Instance().GetElement(path) % args;
} }

6
Sources/Plasma/FeatureLib/pfLocalizationMgr/pfLocalizationMgr.h

@ -60,7 +60,7 @@ protected:
public: public:
virtual ~pfLocalizationMgr(); virtual ~pfLocalizationMgr();
static void Initialize(const std::string & dataPath); static void Initialize(const plString & dataPath);
static void Shutdown(); static void Shutdown();
static pfLocalizationMgr &Instance(void) {return *fInstance;} static pfLocalizationMgr &Instance(void) {return *fInstance;}
static bool InstanceValid(void) {return fInstance != nil;} static bool InstanceValid(void) {return fInstance != nil;}
@ -70,8 +70,8 @@ public:
// want the arguments in a different order (like you had to switch things around for a specific language) // want the arguments in a different order (like you had to switch things around for a specific language)
// then you use %1s, %2s, %3s and so on to specify arguments, these two cannot be mixed and you won't get // then you use %1s, %2s, %3s and so on to specify arguments, these two cannot be mixed and you won't get
// the results you expect if you do mix them. Path is specified by Age.Set.Name // the results you expect if you do mix them. Path is specified by Age.Set.Name
std::wstring GetString(const std::wstring & path, const std::vector<std::wstring> & args); plString GetString(const plString & path, const std::vector<plString> & args);
std::wstring GetString(const std::wstring & path); plString GetString(const plString & path);
}; };
#endif #endif

300
Sources/Plasma/FeatureLib/pfLocalizationMgr/pfLocalizedString.cpp

@ -51,10 +51,6 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
#include "pfLocalizedString.h" #include "pfLocalizedString.h"
// MinGW sucks
#if defined(_WIN32) && !defined(_MSC_VER)
# define swprintf _snwprintf
#endif
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
//// pfLocalizedString functions ///////////////////////////////////// //// pfLocalizedString functions /////////////////////////////////////
@ -62,93 +58,106 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
//// Constructors //////////////////////////////////////////////////// //// Constructors ////////////////////////////////////////////////////
pfLocalizedString::pfLocalizedString(const wchar_t *plainText) pfLocalizedString::pfLocalizedString(const plString & plainText)
: fNumArguments(0)
{ {
fNumArguments = 0;
IConvertFromPlainText(plainText); IConvertFromPlainText(plainText);
} }
pfLocalizedString::pfLocalizedString(const std::wstring & plainText) //// IParameterize ///////////////////////////////////////////////////
{
fNumArguments = 0;
IConvertFromPlainText(plainText);
}
//// IConvertFromPlainText ///////////////////////////////////////////
void pfLocalizedString::IConvertFromPlainText(const std::wstring & plainText) void pfLocalizedString::IParameterize(const plString & inString)
{ {
textBlock curTextBlock; textBlock curTextBlock;
fText.clear(); fNumArguments = 0; // Reset the argument count.
fPlainTextRep = plainText; fText.clear(); // Reset the text blocks.
fNumArguments = 0; // reset the argument count
plString remainder = inString;
plStringStream newText;
int curParameter = 0; int curParameter = 0;
int nextToken = -1;
for (std::wstring::size_type curIndex = 0; curIndex < plainText.size(); curIndex++) while (!remainder.IsEmpty())
{ {
wchar_t curChar = plainText[curIndex]; // Check if we have any params.
bool isLastChar = (curIndex == (plainText.length() - 1)); nextToken = remainder.Find("%");
switch (curChar) if (nextToken != -1)
{ {
case L'\\': // Check it's not escaped.
if (!isLastChar) if ((nextToken == 0) || ((nextToken > 0) && (remainder.CharAt(nextToken-1) != '\\')))
{
// we need to see the next character
curIndex++;
wchar_t nextChar = plainText[curIndex];
if ((nextChar == L'%')||(nextChar == L'\\'))
{
// we recognize it as an escaped character, so add it to the text
curTextBlock.fText += nextChar;
}
// otherwise we don't recognize it and it will be skipped
}
// if it's the last char, just drop it
break;
case L'%':
if (!isLastChar)
{ {
// we need to grab the trailing s character // Check if it has an end (ignoring any terminators we need to cross a space to find).
std::wstring::size_type endArgPos = plainText.find(L"s", curIndex); int endToken = remainder.Substr(nextToken).Find("s");
if (endArgPos != std::wstring::npos) // make sure the s exists if ((endToken != -1) && (remainder.Substr(nextToken, endToken).Find(" ") == -1))
{ {
if (endArgPos == (curIndex + 1)) // no number specifier // Store existing block if it contains anything.
newText << remainder.Substr(0, nextToken);
curTextBlock.fText = newText.GetString().Replace("\\\\", "\\");
if (!curTextBlock.fText.IsEmpty())
{ {
fText.push_back(curTextBlock); fText.push_back(curTextBlock);
newText.Truncate();
}
if (endToken == nextToken + 1)
{
// Store non-indexed param block.
curTextBlock.fIsParam = true; curTextBlock.fIsParam = true;
curTextBlock.fParamIndex = curParameter; curTextBlock.fParamIndex = curParameter++;
curParameter++; curTextBlock.fText = "";
curTextBlock.fText = L"";
fText.push_back(curTextBlock); fText.push_back(curTextBlock);
curTextBlock.fIsParam = false;
curTextBlock.fParamIndex = 0;
} }
else // number specified else
{ {
fText.push_back(curTextBlock); // Store indexed param block.
curTextBlock.fIsParam = true; curTextBlock.fIsParam = true;
curTextBlock.fText = L""; curTextBlock.fParamIndex = remainder.Substr(nextToken + 1, endToken - 1).ToInt(10) - 1; // args start at 1
curTextBlock.fText = "";
std::wstring number = plainText.substr(curIndex + 1, (endArgPos - (curIndex + 1)));
curTextBlock.fParamIndex = (uint8_t)wcstol(number.c_str(), NULL, 10) - 1; // args are 1-based, vectors are 0-based
fText.push_back(curTextBlock); fText.push_back(curTextBlock);
curTextBlock.fIsParam = false;
curTextBlock.fParamIndex = 0;
} }
fNumArguments++; // increment our argument count curTextBlock.fIsParam = false;
curIndex = endArgPos; // update our position curTextBlock.fParamIndex = 0;
fNumArguments++;
// Continue, using the remaining string.
remainder = remainder.Substr(nextToken + endToken + 1);
} }
// if s didn't exist, we just skip this % sign else
{
// We have an unescaped but unterminated %.
// For now, let's just pretend it was escaped;
// This way they'll show up visibly in-game and will be reported.
newText << "%";
remainder = remainder.Substr(nextToken + 1);
}
}
else
{
// Copy the text up to the escape character, skip it, and continue.
newText << remainder.Substr(0, nextToken - 1) << '%';
remainder = remainder.Substr(nextToken + 1);
}
}
else
{
// We're done. Copy the remaining text and finish.
newText << remainder;
remainder = "";
curTextBlock.fText = newText.GetString().Replace("\\\\", "\\");
if (!curTextBlock.fText.IsEmpty())
{
fText.push_back(curTextBlock);
newText.Truncate();
} }
// if it was the last char, we just skip this % sign
break;
default:
curTextBlock.fText += curChar;
break;
} }
} }
fText.push_back(curTextBlock); }
//// IConvertFromPlainText ///////////////////////////////////////////
void pfLocalizedString::IConvertFromPlainText(const plString & plainText)
{
IParameterize(plainText);
IUpdateXML(); IUpdateXML();
} }
@ -157,153 +166,62 @@ void pfLocalizedString::IConvertFromPlainText(const std::wstring & plainText)
void pfLocalizedString::IUpdatePlainText() void pfLocalizedString::IUpdatePlainText()
{ {
fPlainTextRep = L""; plStringStream ss;
for (std::vector<std::wstring>::size_type curIndex = 0; curIndex < fText.size(); curIndex++)
for (std::vector<textBlock>::size_type curIndex = 0; curIndex < fText.size(); curIndex++)
{ {
textBlock curTextBlock = fText[curIndex]; textBlock curTextBlock = fText[curIndex];
if (curTextBlock.fIsParam) if (curTextBlock.fIsParam)
{ {
std::wstring paramStr = L"%"; // Fill in parameter value.
wchar_t buff[256]; ss << "%%" << curTextBlock.fParamIndex + 1 << "s";
swprintf(buff, 256, L"%d", curTextBlock.fParamIndex + 1);
paramStr += buff;
paramStr += L"s";
fPlainTextRep += paramStr;
} }
else else
{ {
// otherwise, we need to copy all the text over, making sure that % and \ are properly escaped // Escape special characters.
for (std::wstring::size_type curChar = 0; curChar < curTextBlock.fText.size(); curChar++) ss << curTextBlock.fText.Replace("\\","\\\\").Replace("%","\\%");
{
if ((curTextBlock.fText[curChar] == L'\\')||(curTextBlock.fText[curChar] == L'%'))
fPlainTextRep += L"\\";
fPlainTextRep += curTextBlock.fText[curChar];
}
} }
} }
fPlainTextRep = ss.GetString();
} }
//// IConvertFromXML ///////////////////////////////////////////////// //// IConvertFromXML /////////////////////////////////////////////////
void pfLocalizedString::IConvertFromXML(const std::wstring & xml) void pfLocalizedString::IConvertFromXML(const plString & xml)
{ {
textBlock curTextBlock; IParameterize(xml);
fText.clear();
fNumArguments = 0; // reset the argument counter
int curParameter = 0;
for (std::wstring::size_type curIndex = 0; curIndex < xml.length(); curIndex++)
{
wchar_t curChar = xml[curIndex];
bool isLastChar = (curIndex == (xml.length() - 1));
switch (curChar)
{ // expat handles the &gt; &lt; and so on stuff for us
case L'\\': // but we want to be able to escape the % sign and the \ character
if (!isLastChar)
{
// we need to see the next character
curIndex++;
wchar_t nextChar = xml[curIndex];
if ((nextChar == L'%')||(nextChar == L'\\'))
{
// we recognize it as an escaped character, so add it to the text
curTextBlock.fText += nextChar;
}
// otherwise we don't recognize it and it will be skipped
}
// if it's the last char, just drop it
break;
case L'%':
if (!isLastChar)
{
// we need to grab the trailing s character
std::wstring::size_type endArgPos = xml.find(L"s", curIndex);
if (endArgPos != std::wstring::npos) // make sure the s exists
{
if (endArgPos == (curIndex + 1)) // no number specifier
{
fText.push_back(curTextBlock);
curTextBlock.fIsParam = true;
curTextBlock.fParamIndex = curParameter;
curParameter++;
curTextBlock.fText = L"";
fText.push_back(curTextBlock);
curTextBlock.fIsParam = false;
curTextBlock.fParamIndex = 0;
}
else // number specified
{
fText.push_back(curTextBlock);
curTextBlock.fIsParam = true;
curTextBlock.fText = L"";
std::wstring number = xml.substr(curIndex + 1, (endArgPos - (curIndex + 1)));
curTextBlock.fParamIndex = (uint8_t)wcstol(number.c_str(), nil, 10) - 1; // args are 1-based, vectors are 0-based
fText.push_back(curTextBlock);
curTextBlock.fIsParam = false;
curTextBlock.fParamIndex = 0;
}
fNumArguments++; // increment the number of arguments
curIndex = endArgPos; // update our position
}
// if s didn't exist, we just skip this % sign
}
// if it was the last char, we just skip this % sign
break;
default:
curTextBlock.fText += curChar;
break;
}
}
fText.push_back(curTextBlock);
IUpdatePlainText(); IUpdatePlainText();
IUpdateXML(); // we don't really get pure xml from the parser (since it auto translates all the &x; stuff) IUpdateXML();
} }
//// IUpdateXML ////////////////////////////////////////////////////// //// IUpdateXML //////////////////////////////////////////////////////
void pfLocalizedString::IUpdateXML() void pfLocalizedString::IUpdateXML()
{ {
fXMLRep = L""; plStringStream ss;
for (std::vector<std::wstring>::size_type curIndex = 0; curIndex < fText.size(); curIndex++) for (std::vector<plString>::size_type curIndex = 0; curIndex < fText.size(); curIndex++)
{ {
textBlock curTextBlock = fText[curIndex]; textBlock curTextBlock = fText[curIndex];
if (curTextBlock.fIsParam) if (curTextBlock.fIsParam)
{ {
std::wstring paramStr = L"%"; // Fill in parameter value.
wchar_t buff[256]; ss << "%%" << curTextBlock.fParamIndex + 1 << "s";
swprintf(buff, 256, L"%d", curTextBlock.fParamIndex + 1);
paramStr += buff;
paramStr += L"s";
fXMLRep += paramStr;
} }
else else
{ {
// otherwise, we need to copy all the text over, making sure that %, &, <, and > are properly converted // Encode XML entities.
for (std::wstring::size_type curChar = 0; curChar < curTextBlock.fText.size(); curChar++) ss << curTextBlock.fText.Replace("%", "\\%").Replace("&", "&amp;").Replace("<", "&lt;").Replace(">", "&gt;");
{
if (curTextBlock.fText[curChar] == L'%')
fXMLRep += L"\\%";
else if (curTextBlock.fText[curChar] == L'&')
fXMLRep += L"&amp;";
else if (curTextBlock.fText[curChar] == L'<')
fXMLRep += L"&lt;";
else if (curTextBlock.fText[curChar] == L'>')
fXMLRep += L"&gt;";
else
fXMLRep += curTextBlock.fText[curChar];
}
} }
} }
fXMLRep = ss.GetString();
} }
//// FromXML ///////////////////////////////////////////////////////// //// FromXML /////////////////////////////////////////////////////////
void pfLocalizedString::FromXML(const std::wstring & xml) void pfLocalizedString::FromXML(const plString & xml)
{ {
IConvertFromXML(xml); IConvertFromXML(xml);
} }
@ -312,32 +230,32 @@ void pfLocalizedString::FromXML(const std::wstring & xml)
bool pfLocalizedString::operator<(pfLocalizedString &obj) bool pfLocalizedString::operator<(pfLocalizedString &obj)
{ {
return (fPlainTextRep < obj.fPlainTextRep); return (fPlainTextRep.Compare(obj.fPlainTextRep) < 0);
} }
bool pfLocalizedString::operator>(pfLocalizedString &obj) bool pfLocalizedString::operator>(pfLocalizedString &obj)
{ {
return (fPlainTextRep > obj.fPlainTextRep); return (fPlainTextRep.Compare(obj.fPlainTextRep) > 0);
} }
bool pfLocalizedString::operator==(pfLocalizedString &obj) bool pfLocalizedString::operator==(pfLocalizedString &obj)
{ {
return (fPlainTextRep == obj.fPlainTextRep); return (fPlainTextRep.Compare(obj.fPlainTextRep) == 0);
} }
bool pfLocalizedString::operator<=(pfLocalizedString &obj) bool pfLocalizedString::operator<=(pfLocalizedString &obj)
{ {
return (fPlainTextRep <= obj.fPlainTextRep); return (fPlainTextRep.Compare(obj.fPlainTextRep) <= 0);
} }
bool pfLocalizedString::operator>=(pfLocalizedString &obj) bool pfLocalizedString::operator>=(pfLocalizedString &obj)
{ {
return (fPlainTextRep >= obj.fPlainTextRep); return (fPlainTextRep.Compare(obj.fPlainTextRep) >= 0);
} }
bool pfLocalizedString::operator!=(pfLocalizedString &obj) bool pfLocalizedString::operator!=(pfLocalizedString &obj)
{ {
return (fPlainTextRep != obj.fPlainTextRep); return (fPlainTextRep.Compare(obj.fPlainTextRep) != 0);
} }
pfLocalizedString pfLocalizedString::operator+(pfLocalizedString &obj) pfLocalizedString pfLocalizedString::operator+(pfLocalizedString &obj)
@ -354,31 +272,25 @@ pfLocalizedString &pfLocalizedString::operator+=(pfLocalizedString &obj)
return *this; return *this;
} }
pfLocalizedString &pfLocalizedString::operator=(const std::wstring & plainText) pfLocalizedString &pfLocalizedString::operator=(const plString & plainText)
{
IConvertFromPlainText(plainText);
return *this;
}
pfLocalizedString &pfLocalizedString::operator=(const wchar_t *plainText)
{ {
IConvertFromPlainText(plainText); IConvertFromPlainText(plainText);
return *this; return *this;
} }
std::wstring pfLocalizedString::operator%(const std::vector<std::wstring> & arguments) plString pfLocalizedString::operator%(const std::vector<plString> & arguments)
{ {
std::wstring retVal = L""; plStringStream ss;
for (std::vector<std::wstring>::size_type curIndex = 0; curIndex < fText.size(); curIndex++) for (std::vector<plString>::size_type curIndex = 0; curIndex < fText.size(); curIndex++)
{ {
if (fText[curIndex].fIsParam) if (fText[curIndex].fIsParam)
{ {
int curParam = fText[curIndex].fParamIndex; int curParam = fText[curIndex].fParamIndex;
if (curParam < arguments.size()) if (curParam < arguments.size())
retVal += arguments[curParam]; ss << arguments[curParam];
} }
else else
retVal += fText[curIndex].fText; ss << fText[curIndex].fText;
} }
return retVal; return ss.GetString();
} }

36
Sources/Plasma/FeatureLib/pfLocalizationMgr/pfLocalizedString.h

@ -51,9 +51,8 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
#define _pfLocalizedString_h #define _pfLocalizedString_h
#include "HeadSpin.h" #include "HeadSpin.h"
#include "plString.h"
#include <vector> #include <vector>
#include <string>
//// pfLocalizedString Class Definition ////////////////////////////// //// pfLocalizedString Class Definition //////////////////////////////
// a small class to handle localized strings and which can take // a small class to handle localized strings and which can take
@ -67,30 +66,30 @@ protected:
struct textBlock struct textBlock
{ {
bool fIsParam; // if true, then this is a parameter, not a string bool fIsParam; // if true, then this is a parameter, not a string
std::wstring fText; plString fText;
uint8_t fParamIndex; uint8_t fParamIndex;
textBlock() : fIsParam(false), fParamIndex(0) {} textBlock() : fIsParam(false), fParamIndex(0) {}
}; };
std::vector<textBlock> fText; // the individual text elements that make up this string std::vector<textBlock> fText; // the individual text elements that make up this string
std::wstring fXMLRep; // the XML representation of this string plString fXMLRep; // the XML representation of this string
std::wstring fPlainTextRep; // the plain text representation of this string plString fPlainTextRep; // the plain text representation of this string
uint16_t fNumArguments; // number of arguments this string has uint16_t fNumArguments; // number of arguments this string has
void IConvertFromPlainText(const std::wstring & plainText); void IParameterize(const plString & inString);
void IConvertFromPlainText(const plString & plainText);
void IUpdatePlainText(); // from the internal representation void IUpdatePlainText(); // from the internal representation
void IConvertFromXML(const std::wstring & xml); void IConvertFromXML(const plString & xml);
void IUpdateXML(); // from the internal representation void IUpdateXML(); // from the internal representation
public: public:
pfLocalizedString() : fNumArguments(0) {} pfLocalizedString() : fNumArguments(0) {}
pfLocalizedString(const wchar_t *plainText); pfLocalizedString(const plString & plainText);
pfLocalizedString(const std::wstring & plainText);
virtual ~pfLocalizedString() {} virtual ~pfLocalizedString() {}
// To translate to and from xml format (where <, > and other signs can't be used) // To translate to and from xml format (where <, > and other signs can't be used)
void FromXML(const std::wstring & xml); void FromXML(const plString & xml);
std::wstring ToXML() {return fXMLRep;} plString ToXML() {return fXMLRep;}
uint16_t GetArgumentCount() {return fNumArguments;} uint16_t GetArgumentCount() {return fNumArguments;}
@ -103,17 +102,14 @@ public:
bool operator>=(pfLocalizedString &obj); bool operator>=(pfLocalizedString &obj);
bool operator!=(pfLocalizedString &obj); bool operator!=(pfLocalizedString &obj);
//operator const wchar_t *() {return fPlainTextRep.c_str();} operator plString() {return fPlainTextRep;}
operator std::wstring() {return fPlainTextRep;}
pfLocalizedString operator+(pfLocalizedString &obj); pfLocalizedString operator+(pfLocalizedString &obj);
pfLocalizedString &operator+=(pfLocalizedString &obj); pfLocalizedString &operator+=(pfLocalizedString &obj);
pfLocalizedString &operator=(const plString & plainText);
pfLocalizedString &operator=(const std::wstring & plainText);
pfLocalizedString &operator=(const wchar_t *plainText);
// Specialized operator for replacing text with arguments // Specialized operator for replacing text with arguments
std::wstring operator%(const std::vector<std::wstring> & arguments); plString operator%(const std::vector<plString> & arguments);
}; };
#endif #endif

4
Sources/Plasma/FeatureLib/pfPython/cyMisc.cpp

@ -2725,11 +2725,11 @@ void cyMisc::ForceCursorShown()
// properly replaced (the list is a list of unicode strings) Name // properly replaced (the list is a list of unicode strings) Name
// is in "Age.Set.Name" format // is in "Age.Set.Name" format
// //
std::wstring cyMisc::GetLocalizedString(std::wstring name, const std::vector<std::wstring> & arguments) plString cyMisc::GetLocalizedString(plString name, const std::vector<plString> & arguments)
{ {
if (pfLocalizationMgr::InstanceValid()) if (pfLocalizationMgr::InstanceValid())
return pfLocalizationMgr::Instance().GetString(name, arguments); return pfLocalizationMgr::Instance().GetString(name, arguments);
return L""; return "";
} }
void cyMisc::EnablePlanarReflections(bool enable) void cyMisc::EnablePlanarReflections(bool enable)

2
Sources/Plasma/FeatureLib/pfPython/cyMisc.h

@ -922,7 +922,7 @@ public:
// properly replaced (the list is a list of unicode strings) Name // properly replaced (the list is a list of unicode strings) Name
// is in "Age.Set.Name" format // is in "Age.Set.Name" format
// //
static std::wstring GetLocalizedString(std::wstring name, const std::vector<std::wstring> & arguments); static plString GetLocalizedString(plString name, const std::vector<plString> & arguments);
static void EnablePlanarReflections(bool enable = true); static void EnablePlanarReflections(bool enable = true);
static void SetGraphicsOptions(int Width, int Height, int ColorDepth, bool Windowed, int NumAASamples, int MaxAnisotropicSamples, bool VSync); static void SetGraphicsOptions(int Width, int Height, int ColorDepth, bool Windowed, int NumAASamples, int MaxAnisotropicSamples, bool VSync);

49
Sources/Plasma/FeatureLib/pfPython/cyMiscGlue.cpp

@ -409,27 +409,12 @@ PYTHON_GLOBAL_METHOD_DEFINITION(PtGetLocalizedString, args, "Params: name, argum
PyErr_SetString(PyExc_TypeError, "PtGetLocalizedString expects a unicode string and a list of unicode strings"); PyErr_SetString(PyExc_TypeError, "PtGetLocalizedString expects a unicode string and a list of unicode strings");
PYTHON_RETURN_ERROR; PYTHON_RETURN_ERROR;
} }
std::wstring name; plString name;
std::vector<std::wstring> argList; std::vector<plString> argList;
// convert name from a string or unicode string // convert name from a string
if (PyUnicode_Check(nameObj)) name = PyString_AsStringEx(nameObj);
{ if (name.IsNull())
int len = PyUnicode_GetSize(nameObj);
wchar_t* buffer = new wchar_t[len + 1];
PyUnicode_AsWideChar((PyUnicodeObject*)nameObj, buffer, len);
buffer[len] = L'\0';
name = buffer;
delete [] buffer;
}
else if (PyString_Check(nameObj))
{
char* temp = PyString_AsString(nameObj);
wchar_t* wTemp = hsStringToWString(temp);
name = wTemp;
delete [] wTemp;
}
else
{ {
PyErr_SetString(PyExc_TypeError, "PtGetLocalizedString expects a unicode string and a list of unicode strings"); PyErr_SetString(PyExc_TypeError, "PtGetLocalizedString expects a unicode string and a list of unicode strings");
PYTHON_RETURN_ERROR; PYTHON_RETURN_ERROR;
@ -448,32 +433,16 @@ PYTHON_GLOBAL_METHOD_DEFINITION(PtGetLocalizedString, args, "Params: name, argum
for (int curItem = 0; curItem < len; curItem++) for (int curItem = 0; curItem < len; curItem++)
{ {
PyObject* item = PyList_GetItem(argObj, curItem); PyObject* item = PyList_GetItem(argObj, curItem);
std::wstring arg = L"INVALID ARG"; plString arg = "INVALID ARG";
if (item == Py_None) // none is allowed, but treated as a blank string if (item == Py_None) // none is allowed, but treated as a blank string
arg = L""; arg = "";
else if (PyUnicode_Check(item)) arg = PyString_AsStringEx(item);
{
int strLen = PyUnicode_GetSize(item);
wchar_t* buffer = new wchar_t[strLen + 1];
PyUnicode_AsWideChar((PyUnicodeObject*)item, buffer, strLen);
buffer[strLen] = L'\0';
arg = buffer;
delete [] buffer;
}
else if (PyString_Check(item))
{
char* temp = PyString_AsString(item);
wchar_t* wTemp = hsStringToWString(temp);
arg = wTemp;
delete [] wTemp;
}
// everything else won't throw an error, but will show up as INVALID ARG in the string // everything else won't throw an error, but will show up as INVALID ARG in the string
argList.push_back(arg); argList.push_back(arg);
} }
} }
std::wstring retVal = cyMisc::GetLocalizedString(name, argList); return PyUnicode_FromStringEx(cyMisc::GetLocalizedString(name, argList));
return PyUnicode_FromWideChar(retVal.c_str(), retVal.length());
} }
PYTHON_GLOBAL_METHOD_DEFINITION(PtDumpLogs, args, "Params: folder\nDumps all current log files to the specified folder (a sub-folder to the log folder)") PYTHON_GLOBAL_METHOD_DEFINITION(PtDumpLogs, args, "Params: folder\nDumps all current log files to the specified folder (a sub-folder to the log folder)")

12
Sources/Tools/MaxComponent/plPickLocalizationDlg.cpp

@ -129,20 +129,20 @@ HTREEITEM plPickLocalizationDlg::IAddVar(std::string name, std::string match, HT
void plPickLocalizationDlg::IAddLocalizations(std::string ageName, std::string setName, std::string itemName) void plPickLocalizationDlg::IAddLocalizations(std::string ageName, std::string setName, std::string itemName)
{ {
std::vector<std::wstring> ages = pfLocalizationDataMgr::Instance().GetAgeList(); std::vector<plString> ages = pfLocalizationDataMgr::Instance().GetAgeList();
for (int curAge = 0; curAge < ages.size(); curAge++) for (int curAge = 0; curAge < ages.size(); curAge++)
{ {
HTREEITEM hAgeItem = IAddVar(WStringToString(ages[curAge]), ageName, TVI_ROOT); HTREEITEM hAgeItem = IAddVar(ages[curAge].c_str(), ageName, TVI_ROOT);
std::vector<std::wstring> sets = pfLocalizationDataMgr::Instance().GetSetList(ages[curAge]); std::vector<plString> sets = pfLocalizationDataMgr::Instance().GetSetList(ages[curAge]);
for (int curSet = 0; curSet < sets.size(); curSet++) for (int curSet = 0; curSet < sets.size(); curSet++)
{ {
std::vector<std::wstring> elements = pfLocalizationDataMgr::Instance().GetElementList(ages[curAge], sets[curSet]); std::vector<plString> elements = pfLocalizationDataMgr::Instance().GetElementList(ages[curAge], sets[curSet]);
HTREEITEM hSetItem = IAddVar(WStringToString(sets[curSet]), setName, hAgeItem); HTREEITEM hSetItem = IAddVar(sets[curSet].c_str(), setName, hAgeItem);
for (int curElement = 0; curElement < elements.size(); curElement++) for (int curElement = 0; curElement < elements.size(); curElement++)
IAddVar(WStringToString(elements[curElement]), itemName, hSetItem); IAddVar(elements[curElement].c_str(), itemName, hSetItem);
} }
} }
} }

2
Sources/Tools/MaxMain/GlobalUtility.cpp

@ -230,7 +230,7 @@ DWORD PlasmaMax::Start()
{ {
std::string clientPath(pathTemp); std::string clientPath(pathTemp);
clientPath += "dat"; clientPath += "dat";
pfLocalizationMgr::Initialize(clientPath); pfLocalizationMgr::Initialize(clientPath.c_str());
} }
return GUPRESULT_KEEP; return GUPRESULT_KEEP;

52
Sources/Tools/plLocalizationEditor/plAddDlgs.cpp

@ -151,7 +151,7 @@ BOOL CALLBACK plAddElementDlg::IDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPAR
int index = (int)SendMessage(GetDlgItem(hDlg, IDC_PARENTAGE), CB_GETCURSEL, (WPARAM)0, (LPARAM)0); int index = (int)SendMessage(GetDlgItem(hDlg, IDC_PARENTAGE), CB_GETCURSEL, (WPARAM)0, (LPARAM)0);
SendMessage(GetDlgItem(hDlg, IDC_PARENTAGE), CB_GETLBTEXT, (WPARAM)index, (LPARAM)buff); SendMessage(GetDlgItem(hDlg, IDC_PARENTAGE), CB_GETLBTEXT, (WPARAM)index, (LPARAM)buff);
pthis->fAgeName = buff; pthis->fAgeName = plString::FromWchar(buff);
pthis->fAgeChanged = true; pthis->fAgeChanged = true;
pthis->IUpdateDlg(hDlg); pthis->IUpdateDlg(hDlg);
} }
@ -160,7 +160,7 @@ BOOL CALLBACK plAddElementDlg::IDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPAR
wchar_t buff[256]; wchar_t buff[256];
GetDlgItemTextW(hDlg, IDC_PARENTAGE, buff, 256); GetDlgItemTextW(hDlg, IDC_PARENTAGE, buff, 256);
pthis->fAgeName = buff; pthis->fAgeName = plString::FromWchar(buff);
pthis->fAgeChanged = true; pthis->fAgeChanged = true;
pthis->IUpdateDlg(hDlg, false); pthis->IUpdateDlg(hDlg, false);
} }
@ -171,7 +171,7 @@ BOOL CALLBACK plAddElementDlg::IDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPAR
int index = (int)SendMessage(GetDlgItem(hDlg, IDC_PARENTSET), CB_GETCURSEL, (WPARAM)0, (LPARAM)0); int index = (int)SendMessage(GetDlgItem(hDlg, IDC_PARENTSET), CB_GETCURSEL, (WPARAM)0, (LPARAM)0);
SendMessage(GetDlgItem(hDlg, IDC_PARENTSET), CB_GETLBTEXT, (WPARAM)index, (LPARAM)buff); SendMessage(GetDlgItem(hDlg, IDC_PARENTSET), CB_GETLBTEXT, (WPARAM)index, (LPARAM)buff);
pthis->fSetName = buff; pthis->fSetName = plString::FromWchar(buff);
pthis->IUpdateDlg(hDlg); pthis->IUpdateDlg(hDlg);
} }
else if (HIWORD(wParam) == CBN_EDITCHANGE && LOWORD(wParam) == IDC_PARENTSET) else if (HIWORD(wParam) == CBN_EDITCHANGE && LOWORD(wParam) == IDC_PARENTSET)
@ -179,14 +179,14 @@ BOOL CALLBACK plAddElementDlg::IDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPAR
wchar_t buff[256]; wchar_t buff[256];
GetDlgItemTextW(hDlg, IDC_PARENTSET, buff, 256); GetDlgItemTextW(hDlg, IDC_PARENTSET, buff, 256);
pthis->fSetName = buff; pthis->fSetName = plString::FromWchar(buff);
pthis->IUpdateDlg(hDlg, false); pthis->IUpdateDlg(hDlg, false);
} }
else if (HIWORD(wParam) == EN_UPDATE && LOWORD(wParam) == IDC_ELEMENTNAME) else if (HIWORD(wParam) == EN_UPDATE && LOWORD(wParam) == IDC_ELEMENTNAME)
{ {
wchar_t buff[256]; wchar_t buff[256];
GetDlgItemTextW(hDlg, IDC_ELEMENTNAME, buff, 256); GetDlgItemTextW(hDlg, IDC_ELEMENTNAME, buff, 256);
pthis->fElementName = buff; pthis->fElementName = plString::FromWchar(buff);
pthis->IUpdateDlg(hDlg); pthis->IUpdateDlg(hDlg);
} }
@ -207,7 +207,7 @@ BOOL CALLBACK plAddElementDlg::IDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPAR
bool plAddElementDlg::IInitDlg(HWND hDlg) bool plAddElementDlg::IInitDlg(HWND hDlg)
{ {
HWND listCtrl = GetDlgItem(hDlg, IDC_PARENTAGE); HWND listCtrl = GetDlgItem(hDlg, IDC_PARENTAGE);
std::vector<std::wstring> ageNames = pfLocalizationDataMgr::Instance().GetAgeList(); std::vector<plString> ageNames = pfLocalizationDataMgr::Instance().GetAgeList();
// add the age names to the list // add the age names to the list
for (int i = 0; i < ageNames.size(); i++) for (int i = 0; i < ageNames.size(); i++)
@ -229,15 +229,15 @@ bool plAddElementDlg::IInitDlg(HWND hDlg)
void plAddElementDlg::IUpdateDlg(HWND hDlg, bool setFocus) void plAddElementDlg::IUpdateDlg(HWND hDlg, bool setFocus)
{ {
std::wstring pathStr = L"Path: " + fAgeName + L"." + fSetName + L"." + fElementName; plString pathStr = plString::Format("Path: %s.%s.%s", fAgeName.c_str(), fSetName.c_str(), fElementName.c_str());
SetDlgItemTextW(hDlg, IDC_PATH, pathStr.c_str()); SetDlgItemTextW(hDlg, IDC_PATH, pathStr.ToWchar());
if (fAgeChanged) // we only update this if the age changed (saves time and prevents weird bugs, like typing backwards) if (fAgeChanged) // we only update this if the age changed (saves time and prevents weird bugs, like typing backwards)
{ {
// now add the sets // now add the sets
HWND listCtrl = GetDlgItem(hDlg, IDC_PARENTSET); HWND listCtrl = GetDlgItem(hDlg, IDC_PARENTSET);
SendMessage(listCtrl, CB_RESETCONTENT, (WPARAM)0, (LPARAM)0); SendMessage(listCtrl, CB_RESETCONTENT, (WPARAM)0, (LPARAM)0);
std::vector<std::wstring> setNames = pfLocalizationDataMgr::Instance().GetSetList(fAgeName); std::vector<plString> setNames = pfLocalizationDataMgr::Instance().GetSetList(fAgeName);
// add the set names to the list // add the set names to the list
for (int i = 0; i < setNames.size(); i++) for (int i = 0; i < setNames.size(); i++)
@ -246,24 +246,24 @@ void plAddElementDlg::IUpdateDlg(HWND hDlg, bool setFocus)
// select the set we currently have // select the set we currently have
int ret = (int)SendMessage(listCtrl, CB_SELECTSTRING, (WPARAM)-1, (LPARAM)fSetName.c_str()); int ret = (int)SendMessage(listCtrl, CB_SELECTSTRING, (WPARAM)-1, (LPARAM)fSetName.c_str());
if (ret == CB_ERR) // couldn't find the string, so just set it as the current string in the edit box if (ret == CB_ERR) // couldn't find the string, so just set it as the current string in the edit box
SetDlgItemTextW(hDlg, IDC_PARENTSET, fSetName.c_str()); SetDlgItemTextW(hDlg, IDC_PARENTSET, fSetName.ToWchar());
fAgeChanged = false; fAgeChanged = false;
} }
if (fSetName != L"" && setFocus) if (!fSetName.IsEmpty() && setFocus)
SetFocus(GetDlgItem(hDlg, IDC_ELEMENTNAME)); SetFocus(GetDlgItem(hDlg, IDC_ELEMENTNAME));
if (fSetName != L"" && fElementName != L"") if (!fSetName.IsEmpty() && fElementName.IsEmpty())
EnableWindow(GetDlgItem(hDlg, IDOK), TRUE); EnableWindow(GetDlgItem(hDlg, IDOK), TRUE);
else else
EnableWindow(GetDlgItem(hDlg, IDOK), FALSE); EnableWindow(GetDlgItem(hDlg, IDOK), FALSE);
} }
plAddElementDlg::plAddElementDlg(std::wstring parentPath) plAddElementDlg::plAddElementDlg(plString parentPath)
{ {
// throw away vars // throw away vars
std::wstring element, lang; plString element, lang;
SplitLocalizationPath(parentPath, fAgeName, fSetName, element, lang); SplitLocalizationPath(parentPath, fAgeName, fSetName, element, lang);
} }
@ -309,7 +309,7 @@ BOOL CALLBACK plAddLocalizationDlg::IDlgProc(HWND hDlg, UINT msg, WPARAM wParam,
int index = (int)SendMessage(GetDlgItem(hDlg, IDC_LANGUAGE), CB_GETCURSEL, (WPARAM)0, (LPARAM)0); int index = (int)SendMessage(GetDlgItem(hDlg, IDC_LANGUAGE), CB_GETCURSEL, (WPARAM)0, (LPARAM)0);
SendMessage(GetDlgItem(hDlg, IDC_LANGUAGE), CB_GETLBTEXT, (WPARAM)index, (LPARAM)buff); SendMessage(GetDlgItem(hDlg, IDC_LANGUAGE), CB_GETLBTEXT, (WPARAM)index, (LPARAM)buff);
pthis->fLanguageName = buff; pthis->fLanguageName = plString::FromWchar(buff);
pthis->IUpdateDlg(hDlg); pthis->IUpdateDlg(hDlg);
} }
break; break;
@ -326,16 +326,16 @@ BOOL CALLBACK plAddLocalizationDlg::IDlgProc(HWND hDlg, UINT msg, WPARAM wParam,
return FALSE; return FALSE;
} }
std::vector<std::wstring> IGetAllLanguageNames() std::vector<plString> IGetAllLanguageNames()
{ {
int numLocales = plLocalization::GetNumLocales(); int numLocales = plLocalization::GetNumLocales();
std::vector<std::wstring> retVal; std::vector<plString> retVal;
for (int curLocale = 0; curLocale <= numLocales; curLocale++) for (int curLocale = 0; curLocale <= numLocales; curLocale++)
{ {
const char *name = plLocalization::GetLanguageName((plLocalization::Language)curLocale); const char *name = plLocalization::GetLanguageName((plLocalization::Language)curLocale);
wchar_t *wName = hsStringToWString(name); wchar_t *wName = hsStringToWString(name);
retVal.push_back(wName); retVal.push_back(plString::FromWchar(wName));
delete [] wName; delete [] wName;
} }
@ -344,13 +344,13 @@ std::vector<std::wstring> IGetAllLanguageNames()
bool plAddLocalizationDlg::IInitDlg(HWND hDlg) bool plAddLocalizationDlg::IInitDlg(HWND hDlg)
{ {
std::wstring pathStr = L"Path: " + fAgeName + L"." + fSetName + L"." + fElementName; plString pathStr = plString::Format("Path: %s.%s.%s", fAgeName.c_str(), fSetName.c_str(), fElementName.c_str());
SetDlgItemTextW(hDlg, IDC_PATH, pathStr.c_str()); SetDlgItemTextW(hDlg, IDC_PATH, pathStr.ToWchar());
std::vector<std::wstring> existingLanguages; std::vector<plString> existingLanguages;
existingLanguages = pfLocalizationDataMgr::Instance().GetLanguages(fAgeName, fSetName, fElementName); existingLanguages = pfLocalizationDataMgr::Instance().GetLanguages(fAgeName, fSetName, fElementName);
std::vector<std::wstring> missingLanguages = IGetAllLanguageNames(); std::vector<plString> missingLanguages = IGetAllLanguageNames();
for (int i = 0; i < existingLanguages.size(); i++) // remove all languages we already have for (int i = 0; i < existingLanguages.size(); i++) // remove all languages we already have
{ {
for (int j = 0; j < missingLanguages.size(); j++) for (int j = 0; j < missingLanguages.size(); j++)
@ -382,7 +382,7 @@ bool plAddLocalizationDlg::IInitDlg(HWND hDlg)
// and put it's value into the internal variable // and put it's value into the internal variable
wchar_t buff[256]; wchar_t buff[256];
GetDlgItemText(hDlg, IDC_LANGUAGE, buff, 256); GetDlgItemText(hDlg, IDC_LANGUAGE, buff, 256);
fLanguageName = buff; fLanguageName = plString::FromWchar(buff);
IUpdateDlg(hDlg); IUpdateDlg(hDlg);
return true; return true;
@ -390,16 +390,16 @@ bool plAddLocalizationDlg::IInitDlg(HWND hDlg)
void plAddLocalizationDlg::IUpdateDlg(HWND hDlg) void plAddLocalizationDlg::IUpdateDlg(HWND hDlg)
{ {
if (fLanguageName != L"") if (!fLanguageName.IsEmpty())
EnableWindow(GetDlgItem(hDlg, IDOK), TRUE); EnableWindow(GetDlgItem(hDlg, IDOK), TRUE);
else else
EnableWindow(GetDlgItem(hDlg, IDOK), FALSE); EnableWindow(GetDlgItem(hDlg, IDOK), FALSE);
} }
plAddLocalizationDlg::plAddLocalizationDlg(std::wstring parentPath) plAddLocalizationDlg::plAddLocalizationDlg(plString parentPath)
{ {
// throw away vars // throw away vars
std::wstring lang; plString lang;
SplitLocalizationPath(parentPath, fAgeName, fSetName, fElementName, lang); SplitLocalizationPath(parentPath, fAgeName, fSetName, fElementName, lang);
} }

14
Sources/Tools/plLocalizationEditor/plAddDlgs.h

@ -45,7 +45,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
#include "HeadSpin.h" #include "HeadSpin.h"
#include "hsWindows.h" #include "hsWindows.h"
#include <string> #include "plString.h"
class plAddElementDlg class plAddElementDlg
{ {
@ -55,13 +55,13 @@ protected:
bool IInitDlg(HWND hDlg); bool IInitDlg(HWND hDlg);
void IUpdateDlg(HWND hDlg, bool setFocus = true); void IUpdateDlg(HWND hDlg, bool setFocus = true);
std::wstring fAgeName, fSetName, fElementName; plString fAgeName, fSetName, fElementName;
bool fAgeChanged; bool fAgeChanged;
public: public:
plAddElementDlg(std::wstring parentPath); plAddElementDlg(plString parentPath);
bool DoPick(HWND parent); // returns true if [Ok] clicked, false otherwise. bool DoPick(HWND parent); // returns true if [Ok] clicked, false otherwise.
std::wstring GetValue() {return fAgeName + L"." + fSetName + L"." + fElementName;} plString GetValue() {return plString::Format("%s.%s.%s", fAgeName.c_str(), fSetName.c_str(), fElementName.c_str());}
}; };
class plAddLocalizationDlg class plAddLocalizationDlg
@ -72,12 +72,12 @@ protected:
bool IInitDlg(HWND hDlg); bool IInitDlg(HWND hDlg);
void IUpdateDlg(HWND hDlg); void IUpdateDlg(HWND hDlg);
std::wstring fAgeName, fSetName, fElementName, fLanguageName; plString fAgeName, fSetName, fElementName, fLanguageName;
public: public:
plAddLocalizationDlg(std::wstring parentPath); plAddLocalizationDlg(plString parentPath);
bool DoPick(HWND parent); // returns true if [Ok] clicked, false otherwise. bool DoPick(HWND parent); // returns true if [Ok] clicked, false otherwise.
std::wstring GetValue() {return fLanguageName;} plString GetValue() {return fLanguageName;}
}; };
#endif #endif

130
Sources/Tools/plLocalizationEditor/plEditDlg.cpp

@ -45,7 +45,6 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
#include "plLocTreeView.h" #include "plLocTreeView.h"
#include "plAddDlgs.h" #include "plAddDlgs.h"
#include "pfLocalizationMgr/pfLocalizationDataMgr.h" #include "pfLocalizationMgr/pfLocalizationDataMgr.h"
#include <map> #include <map>
@ -55,64 +54,40 @@ extern HINSTANCE gInstance;
extern HWND gTreeView; extern HWND gTreeView;
// global data for this dialog // global data for this dialog
std::wstring gCurrentPath = L""; plString gCurrentPath;
// split a subtitle path up into its component parts // split a subtitle path up into its component parts
void SplitLocalizationPath(std::wstring path, std::wstring &ageName, std::wstring &setName, std::wstring &locName, std::wstring &locLanguage) void SplitLocalizationPath(plString path, plString &ageName, plString &setName, plString &locName, plString &locLanguage)
{ {
ageName = setName = locName = locLanguage = L""; ageName = setName = locName = locLanguage = "";
std::wstring::size_type lastPos = 0, curPos = 0; std::vector<plString> tokens = path.Tokenize(".");
// separate the age name out if (tokens.size() >= 1)
curPos = path.find(L"."); ageName = tokens[0];
if (curPos == std::wstring::npos) if (tokens.size() >= 2)
{ setName = tokens[1];
ageName = path; if (tokens.size() >= 3)
return; locName = tokens[2];
} if (tokens.size() >= 4)
ageName = path.substr(0, curPos); locLanguage = tokens[3];
path = path.substr(curPos + 1, path.length());
// separate the set name out
curPos = path.find(L".");
if (curPos == std::wstring::npos)
{
setName = path;
return;
}
setName = path.substr(0, curPos);
path = path.substr(curPos + 1, path.length());
// separate the element out
curPos = path.find(L".");
if (curPos == std::wstring::npos)
{
locName = path;
return;
}
locName = path.substr(0, curPos);
path = path.substr(curPos + 1, path.length());
// what's left is the language
locLanguage = path;
} }
// saves the current localization text to the data manager // saves the current localization text to the data manager
void SaveLocalizationText() void SaveLocalizationText()
{ {
if (gCurrentPath == L"") if (gCurrentPath.IsEmpty())
return; // no path to save return; // no path to save
uint32_t textLen = (uint32_t)SendMessage(GetDlgItem(gEditDlg, IDC_LOCALIZATIONTEXT), WM_GETTEXTLENGTH, (WPARAM)0, (LPARAM)0); uint32_t textLen = (uint32_t)SendMessage(GetDlgItem(gEditDlg, IDC_LOCALIZATIONTEXT), WM_GETTEXTLENGTH, (WPARAM)0, (LPARAM)0);
wchar_t *buffer = new wchar_t[textLen + 2]; wchar_t *buffer = new wchar_t[textLen + 2];
GetDlgItemTextW(gEditDlg, IDC_LOCALIZATIONTEXT, buffer, textLen + 1); GetDlgItemTextW(gEditDlg, IDC_LOCALIZATIONTEXT, buffer, textLen + 1);
buffer[textLen + 1] = 0; buffer[textLen + 1] = 0;
std::wstring plainTextData = buffer; plString plainTextData = plString::FromWchar(buffer);
delete [] buffer; delete [] buffer;
std::wstring ageName, setName, elementName, elementLanguage; plString ageName, setName, elementName, elementLanguage;
SplitLocalizationPath(gCurrentPath, ageName, setName, elementName, elementLanguage); SplitLocalizationPath(gCurrentPath, ageName, setName, elementName, elementLanguage);
std::wstring name = ageName + L"." + setName + L"." + elementName; plString name = plString::Format("%s.%s.%s", ageName.c_str(), setName.c_str(), elementName.c_str());
pfLocalizationDataMgr::Instance().SetElementPlainTextData(name, elementLanguage, plainTextData); pfLocalizationDataMgr::Instance().SetElementPlainTextData(name, elementLanguage, plainTextData);
} }
@ -132,38 +107,37 @@ void EnableDlg(BOOL enable)
} }
// updates the edit dialog based on the path specified // updates the edit dialog based on the path specified
void UpdateEditDlg(std::wstring locPath) void UpdateEditDlg(plString locPath)
{ {
if (locPath == gCurrentPath) if (locPath == gCurrentPath)
return; return;
gCurrentPath = locPath; gCurrentPath = locPath;
std::wstring itemText = L"Text ("; plString itemText = plString::Format("Text (%s):", locPath.c_str());
itemText += locPath + L"):"; SetDlgItemTextW(gEditDlg, IDC_LOCPATH, itemText.ToWchar());
SetDlgItemTextW(gEditDlg, IDC_LOCPATH, itemText.c_str());
std::wstring ageName = L"", setName = L"", elementName = L"", elementLanguage = L""; plString ageName, setName, elementName, elementLanguage;
SplitLocalizationPath(locPath, ageName, setName, elementName, elementLanguage); SplitLocalizationPath(locPath, ageName, setName, elementName, elementLanguage);
// now make sure they've drilled down deep enough to enable the dialog // now make sure they've drilled down deep enough to enable the dialog
if (elementLanguage == L"") // not deep enough if (elementLanguage.IsEmpty()) // not deep enough
EnableDlg(FALSE); EnableDlg(FALSE);
else else
{ {
EnableDlg(TRUE); EnableDlg(TRUE);
std::wstring key = ageName + L"." + setName + L"." + elementName; plString key = plString::Format("%s.%s.%s", ageName.c_str(), setName.c_str(), elementName.c_str());
std::wstring elementText = pfLocalizationDataMgr::Instance().GetElementPlainTextData(key, elementLanguage); plString elementText = pfLocalizationDataMgr::Instance().GetElementPlainTextData(key, elementLanguage);
SetDlgItemTextW(gEditDlg, IDC_LOCALIZATIONTEXT, elementText.c_str()); SetDlgItemTextW(gEditDlg, IDC_LOCALIZATIONTEXT, elementText.ToWchar());
} }
// now to setup the add/delete buttons // now to setup the add/delete buttons
if (elementLanguage != L"") // they have selected a language if (!elementLanguage.IsEmpty()) // they have selected a language
{ {
SetDlgItemText(gEditDlg, IDC_ADD, L"Add Localization"); SetDlgItemText(gEditDlg, IDC_ADD, L"Add Localization");
EnableWindow(GetDlgItem(gEditDlg, IDC_ADD), TRUE); EnableWindow(GetDlgItem(gEditDlg, IDC_ADD), TRUE);
SetDlgItemText(gEditDlg, IDC_DELETE, L"Delete Localization"); SetDlgItemText(gEditDlg, IDC_DELETE, L"Delete Localization");
if (elementLanguage != L"English") // don't allow them to delete the default language if (elementLanguage != "English") // don't allow them to delete the default language
EnableWindow(GetDlgItem(gEditDlg, IDC_DELETE), TRUE); EnableWindow(GetDlgItem(gEditDlg, IDC_DELETE), TRUE);
else else
EnableWindow(GetDlgItem(gEditDlg, IDC_DELETE), FALSE); EnableWindow(GetDlgItem(gEditDlg, IDC_DELETE), FALSE);
@ -173,9 +147,9 @@ void UpdateEditDlg(std::wstring locPath)
SetDlgItemText(gEditDlg, IDC_ADD, L"Add Element"); SetDlgItemText(gEditDlg, IDC_ADD, L"Add Element");
EnableWindow(GetDlgItem(gEditDlg, IDC_ADD), TRUE); EnableWindow(GetDlgItem(gEditDlg, IDC_ADD), TRUE);
SetDlgItemText(gEditDlg, IDC_DELETE, L"Delete Element"); SetDlgItemText(gEditDlg, IDC_DELETE, L"Delete Element");
if (elementName != L"") // the have selected an individual element if (!elementName.IsEmpty()) // they have selected an individual element
{ {
std::vector<std::wstring> elementNames = pfLocalizationDataMgr::Instance().GetElementList(ageName, setName); std::vector<plString> elementNames = pfLocalizationDataMgr::Instance().GetElementList(ageName, setName);
if (elementNames.size() > 1) // they can't delete the only subtitle in a set if (elementNames.size() > 1) // they can't delete the only subtitle in a set
EnableWindow(GetDlgItem(gEditDlg, IDC_DELETE), TRUE); EnableWindow(GetDlgItem(gEditDlg, IDC_DELETE), TRUE);
else else
@ -201,43 +175,43 @@ BOOL HandleCommandMessage(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{ {
SaveLocalizationText(); // save any current changes to the database SaveLocalizationText(); // save any current changes to the database
std::wstring buttonText; plString buttonText;
wchar_t buff[256]; wchar_t buff[256];
GetDlgItemText(gEditDlg, IDC_ADD, buff, 256); GetDlgItemText(gEditDlg, IDC_ADD, buff, 256);
buttonText = buff; buttonText = plString::FromWchar(buff);
if (buttonText == L"Add Element") if (buttonText == "Add Element")
{ {
plAddElementDlg dlg(gCurrentPath); plAddElementDlg dlg(gCurrentPath);
if (dlg.DoPick(gEditDlg)) if (dlg.DoPick(gEditDlg))
{ {
std::wstring path = dlg.GetValue(); // path is age.set.name plString path = dlg.GetValue(); // path is age.set.name
if (!pfLocalizationDataMgr::Instance().AddElement(path)) if (!pfLocalizationDataMgr::Instance().AddElement(path))
MessageBox(gEditDlg, L"Couldn't add new element because one already exists with that name!", L"Error", MB_ICONERROR | MB_OK); MessageBox(gEditDlg, L"Couldn't add new element because one already exists with that name!", L"Error", MB_ICONERROR | MB_OK);
else else
{ {
gCurrentPath = L""; gCurrentPath = "";
plLocTreeView::ClearTreeView(gTreeView); plLocTreeView::ClearTreeView(gTreeView);
plLocTreeView::FillTreeViewFromData(gTreeView, path); plLocTreeView::FillTreeViewFromData(gTreeView, path);
UpdateEditDlg(path); UpdateEditDlg(path);
} }
} }
} }
else if (buttonText == L"Add Localization") else if (buttonText == "Add Localization")
{ {
plAddLocalizationDlg dlg(gCurrentPath); plAddLocalizationDlg dlg(gCurrentPath);
if (dlg.DoPick(gEditDlg)) if (dlg.DoPick(gEditDlg))
{ {
std::wstring newLanguage = dlg.GetValue(); plString newLanguage = dlg.GetValue();
std::wstring ageName, setName, elementName, elementLanguage; plString ageName, setName, elementName, elementLanguage;
SplitLocalizationPath(gCurrentPath, ageName, setName, elementName, elementLanguage); SplitLocalizationPath(gCurrentPath, ageName, setName, elementName, elementLanguage);
std::wstring key = ageName + L"." + setName + L"." + elementName; plString key = plString::Format("%s.%s.%s", ageName.c_str(), setName.c_str(), elementName.c_str());
if (!pfLocalizationDataMgr::Instance().AddLocalization(key, newLanguage)) if (!pfLocalizationDataMgr::Instance().AddLocalization(key, newLanguage))
MessageBox(gEditDlg, L"Couldn't add additional localization!", L"Error", MB_ICONERROR | MB_OK); MessageBox(gEditDlg, L"Couldn't add additional localization!", L"Error", MB_ICONERROR | MB_OK);
else else
{ {
std::wstring path = key + L"." + newLanguage; // select the new language plString path = plString::Format("%s.%s", key.c_str(), newLanguage.c_str());
gCurrentPath = L""; gCurrentPath = "";
plLocTreeView::ClearTreeView(gTreeView); plLocTreeView::ClearTreeView(gTreeView);
plLocTreeView::FillTreeViewFromData(gTreeView, path); plLocTreeView::FillTreeViewFromData(gTreeView, path);
UpdateEditDlg(path); UpdateEditDlg(path);
@ -250,39 +224,39 @@ BOOL HandleCommandMessage(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{ {
SaveLocalizationText(); // save any current changes to the database SaveLocalizationText(); // save any current changes to the database
std::wstring messageText = L"Are you sure that you want to delete " + gCurrentPath + L"?"; plString messageText = plString::Format("Are you sure that you want to delete %s?", gCurrentPath.c_str());
int res = MessageBoxW(gEditDlg, messageText.c_str(), L"Delete", MB_ICONQUESTION | MB_YESNO); int res = MessageBoxW(gEditDlg, messageText.ToWchar(), L"Delete", MB_ICONQUESTION | MB_YESNO);
if (res == IDYES) if (res == IDYES)
{ {
std::wstring buttonText; plString buttonText;
wchar_t buff[256]; wchar_t buff[256];
GetDlgItemText(gEditDlg, IDC_DELETE, buff, 256); GetDlgItemText(gEditDlg, IDC_DELETE, buff, 256);
buttonText = buff; buttonText = plString::FromWchar(buff);
if (buttonText == L"Delete Element") if (buttonText == "Delete Element")
{ {
if (!pfLocalizationDataMgr::Instance().DeleteElement(gCurrentPath)) if (!pfLocalizationDataMgr::Instance().DeleteElement(gCurrentPath))
MessageBox(gEditDlg, L"Couldn't delete element!", L"Error", MB_ICONERROR | MB_OK); MessageBox(gEditDlg, L"Couldn't delete element!", L"Error", MB_ICONERROR | MB_OK);
else else
{ {
std::wstring path = gCurrentPath; plString path = gCurrentPath;
gCurrentPath = L""; gCurrentPath = "";
plLocTreeView::ClearTreeView(gTreeView); plLocTreeView::ClearTreeView(gTreeView);
plLocTreeView::FillTreeViewFromData(gTreeView, path); plLocTreeView::FillTreeViewFromData(gTreeView, path);
UpdateEditDlg(path); UpdateEditDlg(path);
} }
} }
else if (buttonText == L"Delete Localization") else if (buttonText == "Delete Localization")
{ {
std::wstring ageName, setName, elementName, elementLanguage; plString ageName, setName, elementName, elementLanguage;
SplitLocalizationPath(gCurrentPath, ageName, setName, elementName, elementLanguage); SplitLocalizationPath(gCurrentPath, ageName, setName, elementName, elementLanguage);
std::wstring key = ageName + L"." + setName + L"." + elementName; plString key = plString::Format("%s.%s.%s", ageName.c_str(), setName.c_str(), elementName.c_str());
if (!pfLocalizationDataMgr::Instance().DeleteLocalization(key, elementLanguage)) if (!pfLocalizationDataMgr::Instance().DeleteLocalization(key, elementLanguage))
MessageBox(gEditDlg, L"Couldn't delete localization!", L"Error", MB_ICONERROR | MB_OK); MessageBox(gEditDlg, L"Couldn't delete localization!", L"Error", MB_ICONERROR | MB_OK);
else else
{ {
std::wstring path = gCurrentPath; plString path = gCurrentPath;
gCurrentPath = L""; gCurrentPath = "";
plLocTreeView::ClearTreeView(gTreeView); plLocTreeView::ClearTreeView(gTreeView);
plLocTreeView::FillTreeViewFromData(gTreeView, path); plLocTreeView::FillTreeViewFromData(gTreeView, path);
UpdateEditDlg(path); UpdateEditDlg(path);

7
Sources/Tools/plLocalizationEditor/plEditDlg.h

@ -45,7 +45,8 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
#include "HeadSpin.h" #include "HeadSpin.h"
#include "hsWindows.h" #include "hsWindows.h"
#include <string>
class plString;
// Little trick to show a wait cursor while something is working // Little trick to show a wait cursor while something is working
class plWaitCursor class plWaitCursor
@ -63,9 +64,9 @@ public:
} }
}; };
void SplitLocalizationPath(std::wstring path, std::wstring &ageName, std::wstring &setName, std::wstring &locName, std::wstring &locLanguage); void SplitLocalizationPath(plString path, plString &ageName, plString &setName, plString &locName, plString &locLanguage);
void SaveLocalizationText(); void SaveLocalizationText();
void UpdateEditDlg(std::wstring subtitlePath); void UpdateEditDlg(plString subtitlePath);
BOOL CALLBACK EditDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); BOOL CALLBACK EditDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
#endif #endif

52
Sources/Tools/plLocalizationEditor/plLocTreeView.cpp

@ -48,22 +48,26 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
#include "res\resource.h" #include "res\resource.h"
#include <vector> #include <vector>
#include <string> #include <list>
#include "pfLocalizationMgr/pfLocalizationDataMgr.h" #include "pfLocalizationMgr/pfLocalizationDataMgr.h"
extern HINSTANCE gInstance; extern HINSTANCE gInstance;
std::wstring plLocTreeView::fPath = L""; plString plLocTreeView::fPath = "";
HTREEITEM AddLeaf(HWND hTree, HTREEITEM hParent, std::wstring text, bool sort = true) HTREEITEM AddLeaf(HWND hTree, HTREEITEM hParent, plString text, bool sort = true)
{ {
// Semi-hack to keep these around as Win32 expects
static std::list<plStringBuffer<wchar_t>> bufs;
plStringBuffer<wchar_t> buf = text.ToWchar();
bufs.push_back(buf);
TVITEM tvi = {0}; TVITEM tvi = {0};
tvi.mask = TVIF_TEXT | TVIF_PARAM; tvi.mask = TVIF_TEXT | TVIF_PARAM;
tvi.pszText = (wchar_t*)text.c_str(); tvi.pszText = const_cast<LPWSTR>(buf.GetData());
tvi.cchTextMax = (int)text.length(); tvi.cchTextMax = static_cast<int>(text.GetSize());
tvi.lParam = NULL; tvi.lParam = NULL;
TVINSERTSTRUCT tvins = {0}; TVINSERTSTRUCT tvins = {0};
tvins.item = tvi; tvins.item = tvi;
@ -76,15 +80,15 @@ HTREEITEM AddLeaf(HWND hTree, HTREEITEM hParent, std::wstring text, bool sort =
return TreeView_InsertItem(hTree, &tvins); return TreeView_InsertItem(hTree, &tvins);
} }
void plLocTreeView::FillTreeViewFromData(HWND treeCtrl, std::wstring selectionPath) void plLocTreeView::FillTreeViewFromData(HWND treeCtrl, plString selectionPath)
{ {
std::wstring targetAge, targetSet, targetElement, targetLang; plString targetAge, targetSet, targetElement, targetLang;
SplitLocalizationPath(selectionPath, targetAge, targetSet, targetElement, targetLang); SplitLocalizationPath(selectionPath, targetAge, targetSet, targetElement, targetLang);
bool ageMatched = false; bool ageMatched = false;
bool setMatched = false; bool setMatched = false;
bool elementMatched = false; bool elementMatched = false;
std::vector<std::wstring> ages = pfLocalizationDataMgr::Instance().GetAgeList(); std::vector<plString> ages = pfLocalizationDataMgr::Instance().GetAgeList();
for (int curAge = 0; curAge < ages.size(); curAge++) for (int curAge = 0; curAge < ages.size(); curAge++)
{ {
// add the age to the tree // add the age to the tree
@ -99,10 +103,10 @@ void plLocTreeView::FillTreeViewFromData(HWND treeCtrl, std::wstring selectionPa
else else
ageMatched = false; ageMatched = false;
std::vector<std::wstring> sets = pfLocalizationDataMgr::Instance().GetSetList(ages[curAge]); std::vector<plString> sets = pfLocalizationDataMgr::Instance().GetSetList(ages[curAge]);
for (int curSet = 0; curSet < sets.size(); curSet++) for (int curSet = 0; curSet < sets.size(); curSet++)
{ {
std::vector<std::wstring> elements = pfLocalizationDataMgr::Instance().GetElementList(ages[curAge], sets[curSet]); std::vector<plString> elements = pfLocalizationDataMgr::Instance().GetElementList(ages[curAge], sets[curSet]);
HTREEITEM setItem = AddLeaf(treeCtrl, ageItem, sets[curSet]); HTREEITEM setItem = AddLeaf(treeCtrl, ageItem, sets[curSet]);
@ -125,13 +129,13 @@ void plLocTreeView::FillTreeViewFromData(HWND treeCtrl, std::wstring selectionPa
TreeView_EnsureVisible(treeCtrl, subItem); TreeView_EnsureVisible(treeCtrl, subItem);
elementMatched = true; elementMatched = true;
if (targetLang.empty()) if (targetLang.IsEmpty())
targetLang = L"English"; targetLang = "English";
} }
else else
elementMatched = false; elementMatched = false;
std::vector<std::wstring> languages = pfLocalizationDataMgr::Instance().GetLanguages(ages[curAge], sets[curSet], elements[curElement]); std::vector<plString> languages = pfLocalizationDataMgr::Instance().GetLanguages(ages[curAge], sets[curSet], elements[curElement]);
for (int curLang = 0; curLang < languages.size(); curLang++) for (int curLang = 0; curLang < languages.size(); curLang++)
{ {
HTREEITEM langItem = AddLeaf(treeCtrl, subItem, languages[curLang]); HTREEITEM langItem = AddLeaf(treeCtrl, subItem, languages[curLang]);
@ -155,8 +159,8 @@ void plLocTreeView::ClearTreeView(HWND treeCtrl)
void plLocTreeView::SelectionChanged(HWND treeCtrl) void plLocTreeView::SelectionChanged(HWND treeCtrl)
{ {
HTREEITEM hItem = TreeView_GetSelection(treeCtrl); HTREEITEM hItem = TreeView_GetSelection(treeCtrl);
std::vector<std::wstring> path; std::vector<plString> path;
fPath = L""; fPath = "";
while (hItem) while (hItem)
{ {
@ -167,7 +171,7 @@ void plLocTreeView::SelectionChanged(HWND treeCtrl)
tvi.pszText = s; tvi.pszText = s;
tvi.cchTextMax = 200; tvi.cchTextMax = 200;
TreeView_GetItem(treeCtrl, &tvi); TreeView_GetItem(treeCtrl, &tvi);
path.push_back(tvi.pszText); path.push_back(plString::FromWchar(tvi.pszText));
hItem = TreeView_GetParent(treeCtrl, hItem); hItem = TreeView_GetParent(treeCtrl, hItem);
} }
@ -177,15 +181,15 @@ void plLocTreeView::SelectionChanged(HWND treeCtrl)
path.pop_back(); path.pop_back();
if (!path.empty()) if (!path.empty())
fPath += L"."; fPath += ".";
} }
} }
void plLocTreeView::SelectionDblClicked(HWND treeCtrl) void plLocTreeView::SelectionDblClicked(HWND treeCtrl)
{ {
HTREEITEM hItem = TreeView_GetSelection(treeCtrl); HTREEITEM hItem = TreeView_GetSelection(treeCtrl);
std::vector<std::wstring> path; std::vector<plString> path;
fPath = L""; fPath = "";
while (hItem) while (hItem)
{ {
@ -196,7 +200,7 @@ void plLocTreeView::SelectionDblClicked(HWND treeCtrl)
tvi.pszText = s; tvi.pszText = s;
tvi.cchTextMax = 200; tvi.cchTextMax = 200;
TreeView_GetItem(treeCtrl, &tvi); TreeView_GetItem(treeCtrl, &tvi);
path.push_back(tvi.pszText); path.push_back(plString::FromWchar(tvi.pszText));
hItem = TreeView_GetParent(treeCtrl, hItem); hItem = TreeView_GetParent(treeCtrl, hItem);
} }
@ -206,6 +210,6 @@ void plLocTreeView::SelectionDblClicked(HWND treeCtrl)
path.pop_back(); path.pop_back();
if (!path.empty()) if (!path.empty())
fPath += L"."; fPath += ".";
} }
} }

8
Sources/Tools/plLocalizationEditor/plLocTreeView.h

@ -43,21 +43,21 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
#define _plLocTreeView_h #define _plLocTreeView_h
#include "HeadSpin.h" #include "HeadSpin.h"
#include <string> #include "plString.h"
class plLocTreeView class plLocTreeView
{ {
protected: protected:
static std::wstring fPath; static plString fPath;
public: public:
static void FillTreeViewFromData(HWND treeCtrl, std::wstring selectionPath); static void FillTreeViewFromData(HWND treeCtrl, plString selectionPath);
static void ClearTreeView(HWND treeCtrl); static void ClearTreeView(HWND treeCtrl);
static void SelectionChanged(HWND treeCtrl); static void SelectionChanged(HWND treeCtrl);
static void SelectionDblClicked(HWND treeCtrl); static void SelectionDblClicked(HWND treeCtrl);
static std::wstring GetPath() {return fPath;} static plString GetPath() {return fPath;}
}; };
#endif //_plLocTreeView_h #endif //_plLocTreeView_h

4
Sources/Tools/plLocalizationEditor/plLocalizationEditor.cpp

@ -223,7 +223,7 @@ LRESULT CALLBACK HandleCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
bInfo.pidlRoot = NULL; bInfo.pidlRoot = NULL;
bInfo.pszDisplayName = path; bInfo.pszDisplayName = path;
bInfo.lpszTitle = L"Select a localization data directory:"; bInfo.lpszTitle = L"Select a localization data directory:";
bInfo.ulFlags = BIF_EDITBOX; bInfo.ulFlags = BIF_USENEWUI | BIF_VALIDATE | BIF_RETURNONLYFSDIRS | BIF_NONEWFOLDERBUTTON;
itemList = SHBrowseForFolder(&bInfo); itemList = SHBrowseForFolder(&bInfo);
if (itemList != NULL) if (itemList != NULL)
@ -242,7 +242,7 @@ LRESULT CALLBACK HandleCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
delete [] sPath; delete [] sPath;
plLocTreeView::ClearTreeView(gTreeView); plLocTreeView::ClearTreeView(gTreeView);
plLocTreeView::FillTreeViewFromData(gTreeView, L""); plLocTreeView::FillTreeViewFromData(gTreeView, "");
gCurPath = path; gCurPath = path;
SetWindowTitle(hWnd, path); SetWindowTitle(hWnd, path);

Loading…
Cancel
Save