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;
if (fUseLocalizationPath && !fLocalizationPath.IsEmpty() && pfLocalizationMgr::InstanceValid())
drawStr = pfLocalizationMgr::Instance().GetString(fLocalizationPath.ToWchar().GetData());
drawStr = pfLocalizationMgr::Instance().GetString(fLocalizationPath).ToWchar().GetData();
else
{
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"
class plStatusLog;
class plString;
// Helper classes/structs that are only used in this main class
class LocalizationDatabase;
@ -81,49 +82,48 @@ protected:
{
protected:
// 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;
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:
// We will just have very basic functionality
bool exists(const std::wstring & 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)
void erase(const std::wstring & key); // erases the key from the map
bool exists(const plString & key); // returns true if the key exists
bool setExists(const plString & key); // returns true if the age.set exists (ignores name if passed in)
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
WStringVector getSetList(const std::wstring & age); // returns a list of all sets in the specified age
WStringVector getNameList(const std::wstring & age, const std::wstring & set);
std::vector<plString> getAgeList(); // returns a list of all ages in this map
std::vector<plString> getSetList(const plString & age); // returns a list of all sets in the specified age
std::vector<plString> getNameList(const plString & age, const plString & set);
};
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
pf3PartMap<localizedElement> fLocalizedElements;
std::string fDataPath;
plString fDataPath;
localizedElement ICreateLocalizedElement(); // ease of use function that creates a basic localized element object
std::wstring IGetCurrentLanguageName(); // get the name of the current language
WStringVector IGetAllLanguageNames();
plString IGetCurrentLanguageName(); // get the name of the current language
std::vector<plString> IGetAllLanguageNames();
void IConvertElement(LocElementInfo *elementInfo, const std::wstring & curPath);
void IConvertSet(LocSetInfo *setInfo, const std::wstring & curPath);
void IConvertAge(LocAgeInfo *ageInfo, const std::wstring & curPath);
void IConvertElement(LocElementInfo *elementInfo, const plString & curPath);
void IConvertSet(LocSetInfo *setInfo, const plString & 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 std::string & filename, const std::wstring & ageName, const std::wstring & languageName); // Write localization text to the specified file
void IWriteText(const plString & filename, const plString & ageName, const plString & languageName); // Write localization text to the specified file
pfLocalizationDataMgr(const std::string & path);
pfLocalizationDataMgr(const plString & path);
public:
virtual ~pfLocalizationDataMgr();
static void Initialize(const std::string & path);
static void Initialize(const plString & path);
static void Shutdown();
static pfLocalizationDataMgr &Instance(void) {return *fInstance;}
static bool InstanceValid(void) {return fInstance != nil;}
@ -131,32 +131,38 @@ public:
void SetupData();
pfLocalizedString GetElement(const std::wstring & name);
pfLocalizedString GetSpecificElement(const std::wstring & name, const std::wstring & languageName);
pfLocalizedString GetElement(const plString & name);
pfLocalizedString GetSpecificElement(const plString & name, const plString & languageName);
WStringVector GetAgeList() { return fLocalizedElements.getAgeList(); }
WStringVector GetSetList(const std::wstring & ageName) { return fLocalizedElements.getSetList(ageName); }
WStringVector GetElementList(const std::wstring & ageName, const std::wstring & setName)
std::vector<plString> GetAgeList()
{
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);
}
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);
std::wstring GetElementPlainTextData(const std::wstring & name, const std::wstring & languageName);
plString GetElementXMLData(const plString & name, const plString & 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)
bool SetElementXMLData(const std::wstring & name, const std::wstring & languageName, const std::wstring & xmlData);
bool SetElementPlainTextData(const std::wstring & name, const std::wstring & languageName, const std::wstring & plainText);
bool SetElementXMLData(const plString & name, const plString & languageName, const plString & xmlData);
bool SetElementPlainTextData(const plString & name, const plString & languageName, const plString & plainText);
// Addition and deletion functions, return true if successful (editor only)
bool AddLocalization(const std::wstring & name, const std::wstring & newLanguage);
bool AddElement(const std::wstring & name);
bool DeleteLocalization(const std::wstring & name, const std::wstring & languageName);
bool DeleteElement(const std::wstring & name);
bool AddLocalization(const plString & name, const plString & newLanguage);
bool AddElement(const plString & name);
bool DeleteLocalization(const plString & name, const plString & languageName);
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
void WriteDatabaseToDisk(const std::string & path);
void WriteDatabaseToDisk(const plString & path);
void OutputTreeToLog(); // prints the localization tree to the log file
};

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

@ -73,7 +73,7 @@ pfLocalizationMgr::~pfLocalizationMgr()
//// Initialize //////////////////////////////////////////////////////
void pfLocalizationMgr::Initialize(const std::string & dataPath)
void pfLocalizationMgr::Initialize(const plString & dataPath)
{
if (fInstance)
return;
@ -95,13 +95,13 @@ void pfLocalizationMgr::Shutdown()
//// 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;
}
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;
}

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

@ -60,7 +60,7 @@ protected:
public:
virtual ~pfLocalizationMgr();
static void Initialize(const std::string & dataPath);
static void Initialize(const plString & dataPath);
static void Shutdown();
static pfLocalizationMgr &Instance(void) {return *fInstance;}
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)
// 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
std::wstring GetString(const std::wstring & path, const std::vector<std::wstring> & args);
std::wstring GetString(const std::wstring & path);
plString GetString(const plString & path, const std::vector<plString> & args);
plString GetString(const plString & path);
};
#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"
// MinGW sucks
#if defined(_WIN32) && !defined(_MSC_VER)
# define swprintf _snwprintf
#endif
//////////////////////////////////////////////////////////////////////
//// pfLocalizedString functions /////////////////////////////////////
@ -62,93 +58,106 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
//// Constructors ////////////////////////////////////////////////////
pfLocalizedString::pfLocalizedString(const wchar_t *plainText)
pfLocalizedString::pfLocalizedString(const plString & plainText)
: fNumArguments(0)
{
fNumArguments = 0;
IConvertFromPlainText(plainText);
}
pfLocalizedString::pfLocalizedString(const std::wstring & plainText)
{
fNumArguments = 0;
IConvertFromPlainText(plainText);
}
//// IConvertFromPlainText ///////////////////////////////////////////
//// IParameterize ///////////////////////////////////////////////////
void pfLocalizedString::IConvertFromPlainText(const std::wstring & plainText)
void pfLocalizedString::IParameterize(const plString & inString)
{
textBlock curTextBlock;
fText.clear();
fPlainTextRep = plainText;
fNumArguments = 0; // reset the argument count
fNumArguments = 0; // Reset the argument count.
fText.clear(); // Reset the text blocks.
plString remainder = inString;
plStringStream newText;
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];
bool isLastChar = (curIndex == (plainText.length() - 1));
switch (curChar)
// Check if we have any params.
nextToken = remainder.Find("%");
if (nextToken != -1)
{
case L'\\':
if (!isLastChar)
{
// 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)
// Check it's not escaped.
if ((nextToken == 0) || ((nextToken > 0) && (remainder.CharAt(nextToken-1) != '\\')))
{
// we need to grab the trailing s character
std::wstring::size_type endArgPos = plainText.find(L"s", curIndex);
if (endArgPos != std::wstring::npos) // make sure the s exists
// Check if it has an end (ignoring any terminators we need to cross a space to find).
int endToken = remainder.Substr(nextToken).Find("s");
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);
newText.Truncate();
}
if (endToken == nextToken + 1)
{
// Store non-indexed param block.
curTextBlock.fIsParam = true;
curTextBlock.fParamIndex = curParameter;
curParameter++;
curTextBlock.fText = L"";
curTextBlock.fParamIndex = curParameter++;
curTextBlock.fText = "";
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.fText = L"";
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
curTextBlock.fParamIndex = remainder.Substr(nextToken + 1, endToken - 1).ToInt(10) - 1; // args start at 1
curTextBlock.fText = "";
fText.push_back(curTextBlock);
curTextBlock.fIsParam = false;
curTextBlock.fParamIndex = 0;
}
fNumArguments++; // increment our argument count
curIndex = endArgPos; // update our position
curTextBlock.fIsParam = false;
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();
}
@ -157,153 +166,62 @@ void pfLocalizedString::IConvertFromPlainText(const std::wstring & plainText)
void pfLocalizedString::IUpdatePlainText()
{
fPlainTextRep = L"";
for (std::vector<std::wstring>::size_type curIndex = 0; curIndex < fText.size(); curIndex++)
plStringStream ss;
for (std::vector<textBlock>::size_type curIndex = 0; curIndex < fText.size(); curIndex++)
{
textBlock curTextBlock = fText[curIndex];
if (curTextBlock.fIsParam)
{
std::wstring paramStr = L"%";
wchar_t buff[256];
swprintf(buff, 256, L"%d", curTextBlock.fParamIndex + 1);
paramStr += buff;
paramStr += L"s";
fPlainTextRep += paramStr;
// Fill in parameter value.
ss << "%%" << curTextBlock.fParamIndex + 1 << "s";
}
else
{
// otherwise, we need to copy all the text over, making sure that % and \ are properly escaped
for (std::wstring::size_type curChar = 0; curChar < curTextBlock.fText.size(); curChar++)
{
if ((curTextBlock.fText[curChar] == L'\\')||(curTextBlock.fText[curChar] == L'%'))
fPlainTextRep += L"\\";
fPlainTextRep += curTextBlock.fText[curChar];
}
// Escape special characters.
ss << curTextBlock.fText.Replace("\\","\\\\").Replace("%","\\%");
}
}
fPlainTextRep = ss.GetString();
}
//// IConvertFromXML /////////////////////////////////////////////////
void pfLocalizedString::IConvertFromXML(const std::wstring & xml)
void pfLocalizedString::IConvertFromXML(const plString & xml)
{
textBlock curTextBlock;
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);
IParameterize(xml);
IUpdatePlainText();
IUpdateXML(); // we don't really get pure xml from the parser (since it auto translates all the &x; stuff)
IUpdateXML();
}
//// IUpdateXML //////////////////////////////////////////////////////
void pfLocalizedString::IUpdateXML()
{
fXMLRep = L"";
for (std::vector<std::wstring>::size_type curIndex = 0; curIndex < fText.size(); curIndex++)
plStringStream ss;
for (std::vector<plString>::size_type curIndex = 0; curIndex < fText.size(); curIndex++)
{
textBlock curTextBlock = fText[curIndex];
if (curTextBlock.fIsParam)
{
std::wstring paramStr = L"%";
wchar_t buff[256];
swprintf(buff, 256, L"%d", curTextBlock.fParamIndex + 1);
paramStr += buff;
paramStr += L"s";
fXMLRep += paramStr;
// Fill in parameter value.
ss << "%%" << curTextBlock.fParamIndex + 1 << "s";
}
else
{
// otherwise, we need to copy all the text over, making sure that %, &, <, and > are properly converted
for (std::wstring::size_type curChar = 0; curChar < curTextBlock.fText.size(); curChar++)
{
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];
}
// Encode XML entities.
ss << curTextBlock.fText.Replace("%", "\\%").Replace("&", "&amp;").Replace("<", "&lt;").Replace(">", "&gt;");
}
}
fXMLRep = ss.GetString();
}
//// FromXML /////////////////////////////////////////////////////////
void pfLocalizedString::FromXML(const std::wstring & xml)
void pfLocalizedString::FromXML(const plString & xml)
{
IConvertFromXML(xml);
}
@ -312,32 +230,32 @@ void pfLocalizedString::FromXML(const std::wstring & xml)
bool pfLocalizedString::operator<(pfLocalizedString &obj)
{
return (fPlainTextRep < obj.fPlainTextRep);
return (fPlainTextRep.Compare(obj.fPlainTextRep) < 0);
}
bool pfLocalizedString::operator>(pfLocalizedString &obj)
{
return (fPlainTextRep > obj.fPlainTextRep);
return (fPlainTextRep.Compare(obj.fPlainTextRep) > 0);
}
bool pfLocalizedString::operator==(pfLocalizedString &obj)
{
return (fPlainTextRep == obj.fPlainTextRep);
return (fPlainTextRep.Compare(obj.fPlainTextRep) == 0);
}
bool pfLocalizedString::operator<=(pfLocalizedString &obj)
{
return (fPlainTextRep <= obj.fPlainTextRep);
return (fPlainTextRep.Compare(obj.fPlainTextRep) <= 0);
}
bool pfLocalizedString::operator>=(pfLocalizedString &obj)
{
return (fPlainTextRep >= obj.fPlainTextRep);
return (fPlainTextRep.Compare(obj.fPlainTextRep) >= 0);
}
bool pfLocalizedString::operator!=(pfLocalizedString &obj)
{
return (fPlainTextRep != obj.fPlainTextRep);
return (fPlainTextRep.Compare(obj.fPlainTextRep) != 0);
}
pfLocalizedString pfLocalizedString::operator+(pfLocalizedString &obj)
@ -354,31 +272,25 @@ pfLocalizedString &pfLocalizedString::operator+=(pfLocalizedString &obj)
return *this;
}
pfLocalizedString &pfLocalizedString::operator=(const std::wstring & plainText)
{
IConvertFromPlainText(plainText);
return *this;
}
pfLocalizedString &pfLocalizedString::operator=(const wchar_t *plainText)
pfLocalizedString &pfLocalizedString::operator=(const plString & plainText)
{
IConvertFromPlainText(plainText);
return *this;
}
std::wstring pfLocalizedString::operator%(const std::vector<std::wstring> & arguments)
plString pfLocalizedString::operator%(const std::vector<plString> & arguments)
{
std::wstring retVal = L"";
for (std::vector<std::wstring>::size_type curIndex = 0; curIndex < fText.size(); curIndex++)
plStringStream ss;
for (std::vector<plString>::size_type curIndex = 0; curIndex < fText.size(); curIndex++)
{
if (fText[curIndex].fIsParam)
{
int curParam = fText[curIndex].fParamIndex;
if (curParam < arguments.size())
retVal += arguments[curParam];
ss << arguments[curParam];
}
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
#include "HeadSpin.h"
#include "plString.h"
#include <vector>
#include <string>
//// pfLocalizedString Class Definition //////////////////////////////
// a small class to handle localized strings and which can take
@ -67,30 +66,30 @@ protected:
struct textBlock
{
bool fIsParam; // if true, then this is a parameter, not a string
std::wstring fText;
uint8_t fParamIndex;
plString fText;
uint8_t fParamIndex;
textBlock() : fIsParam(false), fParamIndex(0) {}
};
std::vector<textBlock> fText; // the individual text elements that make up this string
std::wstring fXMLRep; // the XML representation of this string
std::wstring fPlainTextRep; // the plain text representation of this string
uint16_t fNumArguments; // number of arguments this string has
std::vector<textBlock> fText; // the individual text elements that make up this string
plString fXMLRep; // the XML representation of this string
plString fPlainTextRep; // the plain text representation of this string
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 IConvertFromXML(const std::wstring & xml);
void IConvertFromXML(const plString & xml);
void IUpdateXML(); // from the internal representation
public:
pfLocalizedString() : fNumArguments(0) {}
pfLocalizedString(const wchar_t *plainText);
pfLocalizedString(const std::wstring & plainText);
pfLocalizedString(const plString & plainText);
virtual ~pfLocalizedString() {}
// To translate to and from xml format (where <, > and other signs can't be used)
void FromXML(const std::wstring & xml);
std::wstring ToXML() {return fXMLRep;}
void FromXML(const plString & xml);
plString ToXML() {return fXMLRep;}
uint16_t GetArgumentCount() {return fNumArguments;}
@ -103,17 +102,14 @@ public:
bool operator>=(pfLocalizedString &obj);
bool operator!=(pfLocalizedString &obj);
//operator const wchar_t *() {return fPlainTextRep.c_str();}
operator std::wstring() {return fPlainTextRep;}
operator plString() {return fPlainTextRep;}
pfLocalizedString operator+(pfLocalizedString &obj);
pfLocalizedString &operator+=(pfLocalizedString &obj);
pfLocalizedString &operator=(const std::wstring & plainText);
pfLocalizedString &operator=(const wchar_t *plainText);
pfLocalizedString &operator=(const plString & plainText);
// Specialized operator for replacing text with arguments
std::wstring operator%(const std::vector<std::wstring> & arguments);
plString operator%(const std::vector<plString> & arguments);
};
#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
// 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())
return pfLocalizationMgr::Instance().GetString(name, arguments);
return L"";
return "";
}
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
// 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 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");
PYTHON_RETURN_ERROR;
}
std::wstring name;
std::vector<std::wstring> argList;
plString name;
std::vector<plString> argList;
// convert name from a string or unicode string
if (PyUnicode_Check(nameObj))
{
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
// convert name from a string
name = PyString_AsStringEx(nameObj);
if (name.IsNull())
{
PyErr_SetString(PyExc_TypeError, "PtGetLocalizedString expects a unicode string and a list of unicode strings");
PYTHON_RETURN_ERROR;
@ -448,32 +433,16 @@ PYTHON_GLOBAL_METHOD_DEFINITION(PtGetLocalizedString, args, "Params: name, argum
for (int curItem = 0; curItem < len; 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
arg = L"";
else if (PyUnicode_Check(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;
}
arg = "";
arg = PyString_AsStringEx(item);
// everything else won't throw an error, but will show up as INVALID ARG in the string
argList.push_back(arg);
}
}
std::wstring retVal = cyMisc::GetLocalizedString(name, argList);
return PyUnicode_FromWideChar(retVal.c_str(), retVal.length());
return PyUnicode_FromStringEx(cyMisc::GetLocalizedString(name, argList));
}
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)
{
std::vector<std::wstring> ages = pfLocalizationDataMgr::Instance().GetAgeList();
std::vector<plString> ages = pfLocalizationDataMgr::Instance().GetAgeList();
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++)
{
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++)
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);
clientPath += "dat";
pfLocalizationMgr::Initialize(clientPath);
pfLocalizationMgr::Initialize(clientPath.c_str());
}
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);
SendMessage(GetDlgItem(hDlg, IDC_PARENTAGE), CB_GETLBTEXT, (WPARAM)index, (LPARAM)buff);
pthis->fAgeName = buff;
pthis->fAgeName = plString::FromWchar(buff);
pthis->fAgeChanged = true;
pthis->IUpdateDlg(hDlg);
}
@ -160,7 +160,7 @@ BOOL CALLBACK plAddElementDlg::IDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPAR
wchar_t buff[256];
GetDlgItemTextW(hDlg, IDC_PARENTAGE, buff, 256);
pthis->fAgeName = buff;
pthis->fAgeName = plString::FromWchar(buff);
pthis->fAgeChanged = true;
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);
SendMessage(GetDlgItem(hDlg, IDC_PARENTSET), CB_GETLBTEXT, (WPARAM)index, (LPARAM)buff);
pthis->fSetName = buff;
pthis->fSetName = plString::FromWchar(buff);
pthis->IUpdateDlg(hDlg);
}
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];
GetDlgItemTextW(hDlg, IDC_PARENTSET, buff, 256);
pthis->fSetName = buff;
pthis->fSetName = plString::FromWchar(buff);
pthis->IUpdateDlg(hDlg, false);
}
else if (HIWORD(wParam) == EN_UPDATE && LOWORD(wParam) == IDC_ELEMENTNAME)
{
wchar_t buff[256];
GetDlgItemTextW(hDlg, IDC_ELEMENTNAME, buff, 256);
pthis->fElementName = buff;
pthis->fElementName = plString::FromWchar(buff);
pthis->IUpdateDlg(hDlg);
}
@ -207,7 +207,7 @@ BOOL CALLBACK plAddElementDlg::IDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPAR
bool plAddElementDlg::IInitDlg(HWND hDlg)
{
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
for (int i = 0; i < ageNames.size(); i++)
@ -229,15 +229,15 @@ bool plAddElementDlg::IInitDlg(HWND hDlg)
void plAddElementDlg::IUpdateDlg(HWND hDlg, bool setFocus)
{
std::wstring pathStr = L"Path: " + fAgeName + L"." + fSetName + L"." + fElementName;
SetDlgItemTextW(hDlg, IDC_PATH, pathStr.c_str());
plString pathStr = plString::Format("Path: %s.%s.%s", fAgeName.c_str(), fSetName.c_str(), fElementName.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)
{
// now add the sets
HWND listCtrl = GetDlgItem(hDlg, IDC_PARENTSET);
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
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
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
SetDlgItemTextW(hDlg, IDC_PARENTSET, fSetName.c_str());
SetDlgItemTextW(hDlg, IDC_PARENTSET, fSetName.ToWchar());
fAgeChanged = false;
}
if (fSetName != L"" && setFocus)
if (!fSetName.IsEmpty() && setFocus)
SetFocus(GetDlgItem(hDlg, IDC_ELEMENTNAME));
if (fSetName != L"" && fElementName != L"")
if (!fSetName.IsEmpty() && fElementName.IsEmpty())
EnableWindow(GetDlgItem(hDlg, IDOK), TRUE);
else
EnableWindow(GetDlgItem(hDlg, IDOK), FALSE);
}
plAddElementDlg::plAddElementDlg(std::wstring parentPath)
plAddElementDlg::plAddElementDlg(plString parentPath)
{
// throw away vars
std::wstring element, lang;
plString 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);
SendMessage(GetDlgItem(hDlg, IDC_LANGUAGE), CB_GETLBTEXT, (WPARAM)index, (LPARAM)buff);
pthis->fLanguageName = buff;
pthis->fLanguageName = plString::FromWchar(buff);
pthis->IUpdateDlg(hDlg);
}
break;
@ -326,16 +326,16 @@ BOOL CALLBACK plAddLocalizationDlg::IDlgProc(HWND hDlg, UINT msg, WPARAM wParam,
return FALSE;
}
std::vector<std::wstring> IGetAllLanguageNames()
std::vector<plString> IGetAllLanguageNames()
{
int numLocales = plLocalization::GetNumLocales();
std::vector<std::wstring> retVal;
std::vector<plString> retVal;
for (int curLocale = 0; curLocale <= numLocales; curLocale++)
{
const char *name = plLocalization::GetLanguageName((plLocalization::Language)curLocale);
wchar_t *wName = hsStringToWString(name);
retVal.push_back(wName);
retVal.push_back(plString::FromWchar(wName));
delete [] wName;
}
@ -344,13 +344,13 @@ std::vector<std::wstring> IGetAllLanguageNames()
bool plAddLocalizationDlg::IInitDlg(HWND hDlg)
{
std::wstring pathStr = L"Path: " + fAgeName + L"." + fSetName + L"." + fElementName;
SetDlgItemTextW(hDlg, IDC_PATH, pathStr.c_str());
plString pathStr = plString::Format("Path: %s.%s.%s", fAgeName.c_str(), fSetName.c_str(), fElementName.c_str());
SetDlgItemTextW(hDlg, IDC_PATH, pathStr.ToWchar());
std::vector<std::wstring> existingLanguages;
std::vector<plString> existingLanguages;
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 j = 0; j < missingLanguages.size(); j++)
@ -382,7 +382,7 @@ bool plAddLocalizationDlg::IInitDlg(HWND hDlg)
// and put it's value into the internal variable
wchar_t buff[256];
GetDlgItemText(hDlg, IDC_LANGUAGE, buff, 256);
fLanguageName = buff;
fLanguageName = plString::FromWchar(buff);
IUpdateDlg(hDlg);
return true;
@ -390,16 +390,16 @@ bool plAddLocalizationDlg::IInitDlg(HWND hDlg)
void plAddLocalizationDlg::IUpdateDlg(HWND hDlg)
{
if (fLanguageName != L"")
if (!fLanguageName.IsEmpty())
EnableWindow(GetDlgItem(hDlg, IDOK), TRUE);
else
EnableWindow(GetDlgItem(hDlg, IDOK), FALSE);
}
plAddLocalizationDlg::plAddLocalizationDlg(std::wstring parentPath)
plAddLocalizationDlg::plAddLocalizationDlg(plString parentPath)
{
// throw away vars
std::wstring lang;
plString 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 "hsWindows.h"
#include <string>
#include "plString.h"
class plAddElementDlg
{
@ -55,13 +55,13 @@ protected:
bool IInitDlg(HWND hDlg);
void IUpdateDlg(HWND hDlg, bool setFocus = true);
std::wstring fAgeName, fSetName, fElementName;
plString fAgeName, fSetName, fElementName;
bool fAgeChanged;
public:
plAddElementDlg(std::wstring parentPath);
plAddElementDlg(plString parentPath);
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
@ -72,12 +72,12 @@ protected:
bool IInitDlg(HWND hDlg);
void IUpdateDlg(HWND hDlg);
std::wstring fAgeName, fSetName, fElementName, fLanguageName;
plString fAgeName, fSetName, fElementName, fLanguageName;
public:
plAddLocalizationDlg(std::wstring parentPath);
plAddLocalizationDlg(plString parentPath);
bool DoPick(HWND parent); // returns true if [Ok] clicked, false otherwise.
std::wstring GetValue() {return fLanguageName;}
plString GetValue() {return fLanguageName;}
};
#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 "plAddDlgs.h"
#include "pfLocalizationMgr/pfLocalizationDataMgr.h"
#include <map>
@ -55,64 +54,40 @@ extern HINSTANCE gInstance;
extern HWND gTreeView;
// global data for this dialog
std::wstring gCurrentPath = L"";
plString gCurrentPath;
// 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"";
std::wstring::size_type lastPos = 0, curPos = 0;
// separate the age name out
curPos = path.find(L".");
if (curPos == std::wstring::npos)
{
ageName = path;
return;
}
ageName = path.substr(0, curPos);
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;
ageName = setName = locName = locLanguage = "";
std::vector<plString> tokens = path.Tokenize(".");
if (tokens.size() >= 1)
ageName = tokens[0];
if (tokens.size() >= 2)
setName = tokens[1];
if (tokens.size() >= 3)
locName = tokens[2];
if (tokens.size() >= 4)
locLanguage = tokens[3];
}
// saves the current localization text to the data manager
void SaveLocalizationText()
{
if (gCurrentPath == L"")
if (gCurrentPath.IsEmpty())
return; // no path to save
uint32_t textLen = (uint32_t)SendMessage(GetDlgItem(gEditDlg, IDC_LOCALIZATIONTEXT), WM_GETTEXTLENGTH, (WPARAM)0, (LPARAM)0);
wchar_t *buffer = new wchar_t[textLen + 2];
GetDlgItemTextW(gEditDlg, IDC_LOCALIZATIONTEXT, buffer, textLen + 1);
buffer[textLen + 1] = 0;
std::wstring plainTextData = buffer;
plString plainTextData = plString::FromWchar(buffer);
delete [] buffer;
std::wstring ageName, setName, elementName, elementLanguage;
plString 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);
}
@ -132,38 +107,37 @@ void EnableDlg(BOOL enable)
}
// updates the edit dialog based on the path specified
void UpdateEditDlg(std::wstring locPath)
void UpdateEditDlg(plString locPath)
{
if (locPath == gCurrentPath)
return;
gCurrentPath = locPath;
std::wstring itemText = L"Text (";
itemText += locPath + L"):";
SetDlgItemTextW(gEditDlg, IDC_LOCPATH, itemText.c_str());
plString itemText = plString::Format("Text (%s):", locPath.c_str());
SetDlgItemTextW(gEditDlg, IDC_LOCPATH, itemText.ToWchar());
std::wstring ageName = L"", setName = L"", elementName = L"", elementLanguage = L"";
plString ageName, setName, elementName, elementLanguage;
SplitLocalizationPath(locPath, ageName, setName, elementName, elementLanguage);
// 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);
else
{
EnableDlg(TRUE);
std::wstring key = ageName + L"." + setName + L"." + elementName;
std::wstring elementText = pfLocalizationDataMgr::Instance().GetElementPlainTextData(key, elementLanguage);
SetDlgItemTextW(gEditDlg, IDC_LOCALIZATIONTEXT, elementText.c_str());
plString key = plString::Format("%s.%s.%s", ageName.c_str(), setName.c_str(), elementName.c_str());
plString elementText = pfLocalizationDataMgr::Instance().GetElementPlainTextData(key, elementLanguage);
SetDlgItemTextW(gEditDlg, IDC_LOCALIZATIONTEXT, elementText.ToWchar());
}
// 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");
EnableWindow(GetDlgItem(gEditDlg, IDC_ADD), TRUE);
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);
else
EnableWindow(GetDlgItem(gEditDlg, IDC_DELETE), FALSE);
@ -173,9 +147,9 @@ void UpdateEditDlg(std::wstring locPath)
SetDlgItemText(gEditDlg, IDC_ADD, L"Add Element");
EnableWindow(GetDlgItem(gEditDlg, IDC_ADD), TRUE);
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
EnableWindow(GetDlgItem(gEditDlg, IDC_DELETE), TRUE);
else
@ -201,43 +175,43 @@ BOOL HandleCommandMessage(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
SaveLocalizationText(); // save any current changes to the database
std::wstring buttonText;
plString buttonText;
wchar_t 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);
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))
MessageBox(gEditDlg, L"Couldn't add new element because one already exists with that name!", L"Error", MB_ICONERROR | MB_OK);
else
{
gCurrentPath = L"";
gCurrentPath = "";
plLocTreeView::ClearTreeView(gTreeView);
plLocTreeView::FillTreeViewFromData(gTreeView, path);
UpdateEditDlg(path);
}
}
}
else if (buttonText == L"Add Localization")
else if (buttonText == "Add Localization")
{
plAddLocalizationDlg dlg(gCurrentPath);
if (dlg.DoPick(gEditDlg))
{
std::wstring newLanguage = dlg.GetValue();
std::wstring ageName, setName, elementName, elementLanguage;
plString newLanguage = dlg.GetValue();
plString 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))
MessageBox(gEditDlg, L"Couldn't add additional localization!", L"Error", MB_ICONERROR | MB_OK);
else
{
std::wstring path = key + L"." + newLanguage; // select the new language
gCurrentPath = L"";
plString path = plString::Format("%s.%s", key.c_str(), newLanguage.c_str());
gCurrentPath = "";
plLocTreeView::ClearTreeView(gTreeView);
plLocTreeView::FillTreeViewFromData(gTreeView, 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
std::wstring messageText = L"Are you sure that you want to delete " + gCurrentPath + L"?";
int res = MessageBoxW(gEditDlg, messageText.c_str(), L"Delete", MB_ICONQUESTION | MB_YESNO);
plString messageText = plString::Format("Are you sure that you want to delete %s?", gCurrentPath.c_str());
int res = MessageBoxW(gEditDlg, messageText.ToWchar(), L"Delete", MB_ICONQUESTION | MB_YESNO);
if (res == IDYES)
{
std::wstring buttonText;
plString buttonText;
wchar_t 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))
MessageBox(gEditDlg, L"Couldn't delete element!", L"Error", MB_ICONERROR | MB_OK);
else
{
std::wstring path = gCurrentPath;
gCurrentPath = L"";
plString path = gCurrentPath;
gCurrentPath = "";
plLocTreeView::ClearTreeView(gTreeView);
plLocTreeView::FillTreeViewFromData(gTreeView, 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);
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))
MessageBox(gEditDlg, L"Couldn't delete localization!", L"Error", MB_ICONERROR | MB_OK);
else
{
std::wstring path = gCurrentPath;
gCurrentPath = L"";
plString path = gCurrentPath;
gCurrentPath = "";
plLocTreeView::ClearTreeView(gTreeView);
plLocTreeView::FillTreeViewFromData(gTreeView, 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 "hsWindows.h"
#include <string>
class plString;
// Little trick to show a wait cursor while something is working
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 UpdateEditDlg(std::wstring subtitlePath);
void UpdateEditDlg(plString subtitlePath);
BOOL CALLBACK EditDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
#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 <vector>
#include <string>
#include <list>
#include "pfLocalizationMgr/pfLocalizationDataMgr.h"
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};
tvi.mask = TVIF_TEXT | TVIF_PARAM;
tvi.pszText = (wchar_t*)text.c_str();
tvi.cchTextMax = (int)text.length();
tvi.lParam = NULL;
tvi.mask = TVIF_TEXT | TVIF_PARAM;
tvi.pszText = const_cast<LPWSTR>(buf.GetData());
tvi.cchTextMax = static_cast<int>(text.GetSize());
tvi.lParam = NULL;
TVINSERTSTRUCT tvins = {0};
tvins.item = tvi;
@ -76,15 +80,15 @@ HTREEITEM AddLeaf(HWND hTree, HTREEITEM hParent, std::wstring text, bool sort =
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);
bool ageMatched = false;
bool setMatched = 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++)
{
// add the age to the tree
@ -99,10 +103,10 @@ void plLocTreeView::FillTreeViewFromData(HWND treeCtrl, std::wstring selectionPa
else
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++)
{
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]);
@ -125,13 +129,13 @@ void plLocTreeView::FillTreeViewFromData(HWND treeCtrl, std::wstring selectionPa
TreeView_EnsureVisible(treeCtrl, subItem);
elementMatched = true;
if (targetLang.empty())
targetLang = L"English";
if (targetLang.IsEmpty())
targetLang = "English";
}
else
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++)
{
HTREEITEM langItem = AddLeaf(treeCtrl, subItem, languages[curLang]);
@ -155,8 +159,8 @@ void plLocTreeView::ClearTreeView(HWND treeCtrl)
void plLocTreeView::SelectionChanged(HWND treeCtrl)
{
HTREEITEM hItem = TreeView_GetSelection(treeCtrl);
std::vector<std::wstring> path;
fPath = L"";
std::vector<plString> path;
fPath = "";
while (hItem)
{
@ -167,7 +171,7 @@ void plLocTreeView::SelectionChanged(HWND treeCtrl)
tvi.pszText = s;
tvi.cchTextMax = 200;
TreeView_GetItem(treeCtrl, &tvi);
path.push_back(tvi.pszText);
path.push_back(plString::FromWchar(tvi.pszText));
hItem = TreeView_GetParent(treeCtrl, hItem);
}
@ -177,15 +181,15 @@ void plLocTreeView::SelectionChanged(HWND treeCtrl)
path.pop_back();
if (!path.empty())
fPath += L".";
fPath += ".";
}
}
void plLocTreeView::SelectionDblClicked(HWND treeCtrl)
{
HTREEITEM hItem = TreeView_GetSelection(treeCtrl);
std::vector<std::wstring> path;
fPath = L"";
std::vector<plString> path;
fPath = "";
while (hItem)
{
@ -196,7 +200,7 @@ void plLocTreeView::SelectionDblClicked(HWND treeCtrl)
tvi.pszText = s;
tvi.cchTextMax = 200;
TreeView_GetItem(treeCtrl, &tvi);
path.push_back(tvi.pszText);
path.push_back(plString::FromWchar(tvi.pszText));
hItem = TreeView_GetParent(treeCtrl, hItem);
}
@ -206,6 +210,6 @@ void plLocTreeView::SelectionDblClicked(HWND treeCtrl)
path.pop_back();
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
#include "HeadSpin.h"
#include <string>
#include "plString.h"
class plLocTreeView
{
protected:
static std::wstring fPath;
static plString fPath;
public:
static void FillTreeViewFromData(HWND treeCtrl, std::wstring selectionPath);
static void FillTreeViewFromData(HWND treeCtrl, plString selectionPath);
static void ClearTreeView(HWND treeCtrl);
static void SelectionChanged(HWND treeCtrl);
static void SelectionDblClicked(HWND treeCtrl);
static std::wstring GetPath() {return fPath;}
static plString GetPath() {return fPath;}
};
#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.pszDisplayName = path;
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);
if (itemList != NULL)
@ -242,7 +242,7 @@ LRESULT CALLBACK HandleCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
delete [] sPath;
plLocTreeView::ClearTreeView(gTreeView);
plLocTreeView::FillTreeViewFromData(gTreeView, L"");
plLocTreeView::FillTreeViewFromData(gTreeView, "");
gCurPath = path;
SetWindowTitle(hWnd, path);

Loading…
Cancel
Save