Browse Source

Import plLocalizationEditor

Branan Purvine-Riley 13 years ago committed by branan
parent
commit
7500c9f992
  1. 1
      Sources/Tools/CMakeLists.txt
  2. 41
      Sources/Tools/plLocalizationEditor/CMakeLists.txt
  3. 413
      Sources/Tools/plLocalizationEditor/plAddDlgs.cpp
  4. 84
      Sources/Tools/plLocalizationEditor/plAddDlgs.h
  5. 316
      Sources/Tools/plLocalizationEditor/plEditDlg.cpp
  6. 72
      Sources/Tools/plLocalizationEditor/plEditDlg.h
  7. 213
      Sources/Tools/plLocalizationEditor/plLocTreeView.cpp
  8. 65
      Sources/Tools/plLocalizationEditor/plLocTreeView.h
  9. 394
      Sources/Tools/plLocalizationEditor/plLocalizationEditor.cpp
  10. BIN
      Sources/Tools/plLocalizationEditor/res/icon1.ico
  11. 268
      Sources/Tools/plLocalizationEditor/res/plLocalizationEditor.rc
  12. 51
      Sources/Tools/plLocalizationEditor/res/resource.h

1
Sources/Tools/CMakeLists.txt

@ -1,5 +1,6 @@
#add_subdirectory(Migration) #add_subdirectory(Migration)
#add_subdirectory(plDatMerger) #add_subdirectory(plDatMerger)
add_subdirectory(plLocalizationEditor)
add_subdirectory(plResBrowser) add_subdirectory(plResBrowser)
if(FREETYPE_FOUND) if(FREETYPE_FOUND)

41
Sources/Tools/plLocalizationEditor/CMakeLists.txt

@ -0,0 +1,41 @@
include_directories("../../Plasma/CoreLib")
include_directories("../../Plasma/NucleusLib")
include_directories("../../Plasma/NucleusLib/inc")
include_directories("../../Plasma/PubUtilLib")
include_directories("../../Plasma/FeatureLib")
add_definitions("-DUNICODE")
set(plLocalizationEditor_HEADERS
plAddDlgs.h
plEditDlg.h
plLocTreeView.h
)
set(plLocalizationEditor_SOURCES
plAddDlgs.cpp
plEditDlg.cpp
plLocalizationEditor.cpp
plLocTreeView.cpp
)
set(plLocalizationEditor_RESOURCES
res/plLocalizationEditor.rc
res/resource.h
res/icon1.ico
)
add_executable(plLocalizationEditor WIN32 ${plLocalizationEditor_HEADERS} ${plLocalizationEditor_SOURCES} ${plLocalizationEditor_RESOURCES})
target_link_libraries(plLocalizationEditor CoreLib)
target_link_libraries(plLocalizationEditor CoreLibExe)
target_link_libraries(plLocalizationEditor pnProduct)
target_link_libraries(plLocalizationEditor pnSceneObject)
target_link_libraries(plLocalizationEditor plResMgr)
target_link_libraries(plLocalizationEditor pfLocalizationMgr)
target_link_libraries(plLocalizationEditor ${EXPAT_LIBRARY})
target_link_libraries(plLocalizationEditor comctl32)
source_group("Source Files" FILES ${plLocalizationEditor_SOURCES})
source_group("Header Files" FILES ${plLocalizationEditor_HEADERS})
source_group("Resource Files" FILES ${plLocalizationEditor_RESOURCES})

413
Sources/Tools/plLocalizationEditor/plAddDlgs.cpp

@ -0,0 +1,413 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
// basic classes for encapsulating the add dialogs
#include "res/resource.h"
#include "plAddDlgs.h"
#include "plEditDlg.h"
#include "hsUtils.h"
#include "plResMgr/plLocalization.h"
#include "pfLocalizationMgr/pfLocalizationDataMgr.h"
#include <vector>
#include <map>
extern HINSTANCE gInstance;
// very simple subclass for edit controls (and combo boxes) so that they only accept alphanumeric values
class AlphaNumericEditCtrl
{
int fCtrlID;
HWND fOwner, fEditBox;
LONG_PTR fPrevProc;
public:
AlphaNumericEditCtrl() : fCtrlID(0), fOwner(NULL), fEditBox(NULL), fPrevProc(NULL) {}
~AlphaNumericEditCtrl() {}
void Setup(int ctrlID, HWND owner, bool comboBox);
static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
};
std::map<int, AlphaNumericEditCtrl> editBoxMap;
// basic setup of the edit control
void AlphaNumericEditCtrl::Setup(int ctrlID, HWND owner, bool comboBox)
{
fCtrlID = ctrlID;
fOwner = owner;
// if we're a combo box, we need to subclass the edit control, not the combo box
if (comboBox)
{
COMBOBOXINFO cbinfo;
cbinfo.cbSize = sizeof(COMBOBOXINFO);
GetComboBoxInfo(GetDlgItem(fOwner, fCtrlID), &cbinfo);
fEditBox = cbinfo.hwndItem;
}
else
fEditBox = GetDlgItem(fOwner, fCtrlID);
// subclass the edit box so we can filter input (don't ask me why we have to double cast the
// function pointer to get rid of the compiler warning)
fPrevProc = SetWindowLongPtr(fEditBox, GWLP_WNDPROC, (LONG)(LONG_PTR)AlphaNumericEditCtrl::WndProc);
editBoxMap[fCtrlID] = *this;
}
// Message handler for our edit box
LRESULT CALLBACK AlphaNumericEditCtrl::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int ctrlID = GetDlgCtrlID(hWnd);
if (editBoxMap.find(ctrlID) == editBoxMap.end()) // control ID doesn't exist, so it's probably a combo boxes' edit ctrl
ctrlID = GetDlgCtrlID(GetParent(hWnd)); // so grab the parent's ID number instead
switch (message)
{
case WM_CHAR:
{
AlphaNumericEditCtrl editBox = editBoxMap[ctrlID];
char theChar = (char)wParam;
// we only accept 0-9, a-z, A-Z, or backspace
if ((theChar < '0' || theChar > '9') && (theChar < 'a' || theChar > 'z') && (theChar < 'A' || theChar >'Z') && !(theChar == VK_BACK))
{
MessageBeep(-1); // alert the user
return FALSE; // and make sure the default handler doesn't get it
}
}
}
// Any messages we don't process must be passed onto the original window function
return CallWindowProc((WNDPROC)editBoxMap[ctrlID].fPrevProc, hWnd, message, wParam, lParam);
}
// plAddElementDlg - dialog for adding a single element
BOOL CALLBACK plAddElementDlg::IDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
static plAddElementDlg* pthis = NULL;
switch (msg)
{
case WM_INITDIALOG:
pthis = (plAddElementDlg*)lParam;
if (!pthis->IInitDlg(hDlg))
EndDialog(hDlg, 0);
return FALSE;
case WM_COMMAND:
if (HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDOK)
{
EndDialog(hDlg, 1);
return TRUE;
}
else if (HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, 0);
return TRUE;
}
else if (HIWORD(wParam) == CBN_SELCHANGE && LOWORD(wParam) == IDC_PARENTAGE)
{
wchar_t buff[256];
// we do this whole get sel, get item because get text won't return the updated text
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->fAgeChanged = true;
pthis->IUpdateDlg(hDlg);
}
else if (HIWORD(wParam) == CBN_EDITCHANGE && LOWORD(wParam) == IDC_PARENTAGE)
{
wchar_t buff[256];
GetDlgItemTextW(hDlg, IDC_PARENTAGE, buff, 256);
pthis->fAgeName = buff;
pthis->fAgeChanged = true;
pthis->IUpdateDlg(hDlg, false);
}
else if (HIWORD(wParam) == CBN_SELCHANGE && LOWORD(wParam) == IDC_PARENTSET)
{
wchar_t buff[256];
// we do this whole get sel, get item because get text won't return the updated text
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->IUpdateDlg(hDlg);
}
else if (HIWORD(wParam) == CBN_EDITCHANGE && LOWORD(wParam) == IDC_PARENTSET)
{
wchar_t buff[256];
GetDlgItemTextW(hDlg, IDC_PARENTSET, buff, 256);
pthis->fSetName = 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->IUpdateDlg(hDlg);
}
break;
case WM_SYSCOMMAND:
switch (wParam)
{
case SC_CLOSE:
EndDialog(hDlg, 0);
return TRUE;
}
break;
}
return FALSE;
}
bool plAddElementDlg::IInitDlg(HWND hDlg)
{
HWND listCtrl = GetDlgItem(hDlg, IDC_PARENTAGE);
std::vector<std::wstring> ageNames = pfLocalizationDataMgr::Instance().GetAgeList();
// add the age names to the list
for (int i = 0; i < ageNames.size(); i++)
SendMessage(listCtrl, CB_ADDSTRING, (WPARAM)0, (LPARAM)ageNames[i].c_str());
// select the age we were given
SendMessage(listCtrl, CB_SELECTSTRING, (WPARAM)-1, (LPARAM)fAgeName.c_str());
AlphaNumericEditCtrl ageCtrl, setCtrl, subCtrl;
ageCtrl.Setup(IDC_PARENTAGE, hDlg, true);
setCtrl.Setup(IDC_PARENTSET, hDlg, true);
subCtrl.Setup(IDC_ELEMENTNAME, hDlg, false);
fAgeChanged = true;
IUpdateDlg(hDlg);
return true;
}
void plAddElementDlg::IUpdateDlg(HWND hDlg, bool setFocus)
{
std::wstring pathStr = L"Path: " + fAgeName + L"." + fSetName + L"." + fElementName;
SetDlgItemTextW(hDlg, IDC_PATH, pathStr.c_str());
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);
// add the set names to the list
for (int i = 0; i < setNames.size(); i++)
SendMessage(listCtrl, CB_ADDSTRING, (WPARAM)0, (LPARAM)setNames[i].c_str());
// 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());
fAgeChanged = false;
}
if (fSetName != L"" && setFocus)
SetFocus(GetDlgItem(hDlg, IDC_ELEMENTNAME));
if (fSetName != L"" && fElementName != L"")
EnableWindow(GetDlgItem(hDlg, IDOK), TRUE);
else
EnableWindow(GetDlgItem(hDlg, IDOK), FALSE);
}
plAddElementDlg::plAddElementDlg(std::wstring parentPath)
{
// throw away vars
std::wstring element, lang;
SplitLocalizationPath(parentPath, fAgeName, fSetName, element, lang);
}
bool plAddElementDlg::DoPick(HWND parent)
{
INT_PTR ret = DialogBoxParam(gInstance, MAKEINTRESOURCE(IDD_ADDELEMENT),
parent, IDlgProc, (LPARAM)this);
editBoxMap.clear();
return (ret != 0);
}
// plAddLocalizationDlg - dialog for adding a single localization
BOOL CALLBACK plAddLocalizationDlg::IDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
static plAddLocalizationDlg* pthis = NULL;
switch (msg)
{
case WM_INITDIALOG:
pthis = (plAddLocalizationDlg*)lParam;
if (!pthis->IInitDlg(hDlg))
EndDialog(hDlg, 0);
return FALSE;
case WM_COMMAND:
if (HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDOK)
{
EndDialog(hDlg, 1);
return TRUE;
}
else if (HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, 0);
return TRUE;
}
else if (HIWORD(wParam) == CBN_SELCHANGE && LOWORD(wParam) == IDC_LANGUAGE)
{
wchar_t buff[256];
// we do this whole get sel, get item because get text won't return the updated text
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->IUpdateDlg(hDlg);
}
break;
case WM_SYSCOMMAND:
switch (wParam)
{
case SC_CLOSE:
EndDialog(hDlg, 0);
return TRUE;
}
break;
}
return FALSE;
}
std::vector<std::wstring> IGetAllLanguageNames()
{
int numLocales = plLocalization::GetNumLocales();
std::vector<std::wstring> 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);
delete [] wName;
}
return retVal;
}
bool plAddLocalizationDlg::IInitDlg(HWND hDlg)
{
std::wstring pathStr = L"Path: " + fAgeName + L"." + fSetName + L"." + fElementName;
SetDlgItemTextW(hDlg, IDC_PATH, pathStr.c_str());
std::vector<std::wstring> existingLanguages;
existingLanguages = pfLocalizationDataMgr::Instance().GetLanguages(fAgeName, fSetName, fElementName);
std::vector<std::wstring> missingLanguages = IGetAllLanguageNames();
for (int i = 0; i < existingLanguages.size(); i++) // remove all languages we already have
{
for (int j = 0; j < missingLanguages.size(); j++)
{
if (missingLanguages[j] == existingLanguages[i])
{
missingLanguages.erase(missingLanguages.begin() + j);
j--;
}
}
}
HWND listCtrl = GetDlgItem(hDlg, IDC_LANGUAGE);
// see if any languages are missing
if (missingLanguages.size() == 0)
{
// none are missing, so disable the control
EnableWindow(listCtrl, FALSE);
IUpdateDlg(hDlg);
return true;
}
// add the missing languages to the list
for (int i = 0; i < missingLanguages.size(); i++)
SendMessage(listCtrl, CB_ADDSTRING, (WPARAM)0, (LPARAM)missingLanguages[i].c_str());
// select the first language in the list
SendMessage(listCtrl, CB_SETCURSEL, (WPARAM)0, (LPARAM)0);
// and put it's value into the internal variable
wchar_t buff[256];
GetDlgItemText(hDlg, IDC_LANGUAGE, buff, 256);
fLanguageName = buff;
IUpdateDlg(hDlg);
return true;
}
void plAddLocalizationDlg::IUpdateDlg(HWND hDlg)
{
if (fLanguageName != L"")
EnableWindow(GetDlgItem(hDlg, IDOK), TRUE);
else
EnableWindow(GetDlgItem(hDlg, IDOK), FALSE);
}
plAddLocalizationDlg::plAddLocalizationDlg(std::wstring parentPath)
{
// throw away vars
std::wstring lang;
SplitLocalizationPath(parentPath, fAgeName, fSetName, fElementName, lang);
}
bool plAddLocalizationDlg::DoPick(HWND parent)
{
INT_PTR ret = DialogBoxParam(gInstance, MAKEINTRESOURCE(IDD_ADDLOCALIZATION),
parent, IDlgProc, (LPARAM)this);
return (ret != 0);
}

84
Sources/Tools/plLocalizationEditor/plAddDlgs.h

@ -0,0 +1,84 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
// basic classes for encapsulating the add dialogs
#ifndef __plAddDlgs_h__
#define __plAddDlgs_h__
#include <string>
#define WIN32_LEAN_AND_MEAN
#include <WinSock2.h>
#include <Windows.h>
class plAddElementDlg
{
protected:
static BOOL CALLBACK IDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
bool IInitDlg(HWND hDlg);
void IUpdateDlg(HWND hDlg, bool setFocus = true);
std::wstring fAgeName, fSetName, fElementName;
bool fAgeChanged;
public:
plAddElementDlg(std::wstring parentPath);
bool DoPick(HWND parent); // returns true if [Ok] clicked, false otherwise.
std::wstring GetValue() {return fAgeName + L"." + fSetName + L"." + fElementName;}
};
class plAddLocalizationDlg
{
protected:
static BOOL CALLBACK IDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
bool IInitDlg(HWND hDlg);
void IUpdateDlg(HWND hDlg);
std::wstring fAgeName, fSetName, fElementName, fLanguageName;
public:
plAddLocalizationDlg(std::wstring parentPath);
bool DoPick(HWND parent); // returns true if [Ok] clicked, false otherwise.
std::wstring GetValue() {return fLanguageName;}
};
#endif

316
Sources/Tools/plLocalizationEditor/plEditDlg.cpp

@ -0,0 +1,316 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
// Basic edit dialog stuff
#include "plEditDlg.h"
#include "res/resource.h"
#include "plLocTreeView.h"
#include "plAddDlgs.h"
#include "hsUtils.h"
#include "pfLocalizationMgr/pfLocalizationDataMgr.h"
#include <map>
HWND gEditDlg = NULL;
extern HINSTANCE gInstance;
extern HWND gTreeView;
// global data for this dialog
std::wstring gCurrentPath = L"";
// 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)
{
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;
}
// saves the current localization text to the data manager
void SaveLocalizationText()
{
if (gCurrentPath == L"")
return; // no path to save
UInt32 textLen = (UInt32)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;
delete [] buffer;
std::wstring ageName, setName, elementName, elementLanguage;
SplitLocalizationPath(gCurrentPath, ageName, setName, elementName, elementLanguage);
std::wstring name = ageName + L"." + setName + L"." + elementName;
pfLocalizationDataMgr::Instance().SetElementPlainTextData(name, elementLanguage, plainTextData);
}
// Reset all controls to their default values (except for static controls)
void ResetDlgDefaults()
{
SetDlgItemTextW(gEditDlg, IDC_LOCALIZATIONTEXT, L"");
}
// Enable/disable all edit controls (some won't enable/disable unless an audio file is loaded and the subtitle is timed)
void EnableDlg(BOOL enable)
{
if (!enable)
ResetDlgDefaults(); // reset controls to defaults
EnableWindow(GetDlgItem(gEditDlg, IDC_LOCALIZATIONTEXT), enable);
}
// updates the edit dialog based on the path specified
void UpdateEditDlg(std::wstring locPath)
{
if (locPath == gCurrentPath)
return;
gCurrentPath = locPath;
std::wstring itemText = L"Text (";
itemText += locPath + L"):";
SetDlgItemTextW(gEditDlg, IDC_LOCPATH, itemText.c_str());
std::wstring ageName = L"", setName = L"", elementName = L"", elementLanguage = L"";
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
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());
}
// now to setup the add/delete buttons
if (elementLanguage != L"") // 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
EnableWindow(GetDlgItem(gEditDlg, IDC_DELETE), TRUE);
else
EnableWindow(GetDlgItem(gEditDlg, IDC_DELETE), FALSE);
}
else // they have selected something else
{
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
{
std::vector<std::wstring> 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
EnableWindow(GetDlgItem(gEditDlg, IDC_DELETE), FALSE);
}
else
EnableWindow(GetDlgItem(gEditDlg, IDC_DELETE), FALSE);
}
}
BOOL HandleCommandMessage(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
int wmID, wmEvent;
wmID = LOWORD(wParam);
wmEvent = HIWORD(wParam);
switch (wmEvent)
{
case BN_CLICKED:
switch (wmID)
{
case IDC_ADD:
{
SaveLocalizationText(); // save any current changes to the database
std::wstring buttonText;
wchar_t buff[256];
GetDlgItemText(gEditDlg, IDC_ADD, buff, 256);
buttonText = buff;
if (buttonText == L"Add Element")
{
plAddElementDlg dlg(gCurrentPath);
if (dlg.DoPick(gEditDlg))
{
std::wstring 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"";
plLocTreeView::ClearTreeView(gTreeView);
plLocTreeView::FillTreeViewFromData(gTreeView, path);
UpdateEditDlg(path);
}
}
}
else if (buttonText == L"Add Localization")
{
plAddLocalizationDlg dlg(gCurrentPath);
if (dlg.DoPick(gEditDlg))
{
std::wstring newLanguage = dlg.GetValue();
std::wstring ageName, setName, elementName, elementLanguage;
SplitLocalizationPath(gCurrentPath, ageName, setName, elementName, elementLanguage);
std::wstring key = ageName + L"." + setName + L"." + elementName;
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"";
plLocTreeView::ClearTreeView(gTreeView);
plLocTreeView::FillTreeViewFromData(gTreeView, path);
UpdateEditDlg(path);
}
}
}
return FALSE;
}
case IDC_DELETE:
{
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);
if (res == IDYES)
{
std::wstring buttonText;
wchar_t buff[256];
GetDlgItemText(gEditDlg, IDC_DELETE, buff, 256);
buttonText = buff;
if (buttonText == L"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"";
plLocTreeView::ClearTreeView(gTreeView);
plLocTreeView::FillTreeViewFromData(gTreeView, path);
UpdateEditDlg(path);
}
}
else if (buttonText == L"Delete Localization")
{
std::wstring ageName, setName, elementName, elementLanguage;
SplitLocalizationPath(gCurrentPath, ageName, setName, elementName, elementLanguage);
std::wstring key = ageName + L"." + setName + L"." + elementName;
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"";
plLocTreeView::ClearTreeView(gTreeView);
plLocTreeView::FillTreeViewFromData(gTreeView, path);
UpdateEditDlg(path);
}
}
}
}
return FALSE;
}
}
return (BOOL)DefWindowProc(hWnd, msg, wParam, lParam);
}
// our dialog's window procedure
BOOL CALLBACK EditDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_INITDIALOG:
{
gEditDlg = hWnd;
EnableDlg(FALSE);
}
break;
case WM_COMMAND:
return HandleCommandMessage(hWnd, msg, wParam, lParam);
}
return FALSE;
}

72
Sources/Tools/plLocalizationEditor/plEditDlg.h

@ -0,0 +1,72 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
// Basic edit dialog stuff
#ifndef _pfEditDlg_h
#define _pfEditDlg_h
#define WIN32_LEAN_AND_MEAN
#include <WinSock2.h>
#include <Windows.h>
#include <string>
// Little trick to show a wait cursor while something is working
class plWaitCursor
{
HCURSOR fOrig;
public:
plWaitCursor()
{
fOrig = SetCursor(LoadCursor(NULL, IDC_WAIT));
}
~plWaitCursor()
{
SetCursor(fOrig);
}
};
void SplitLocalizationPath(std::wstring path, std::wstring &ageName, std::wstring &setName, std::wstring &locName, std::wstring &locLanguage);
void SaveLocalizationText();
void UpdateEditDlg(std::wstring subtitlePath);
BOOL CALLBACK EditDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
#endif

213
Sources/Tools/plLocalizationEditor/plLocTreeView.cpp

@ -0,0 +1,213 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#include "plLocTreeView.h"
#include "plEditDlg.h"
#define WIN32_LEAN_AND_MEAN
#include <WinSock2.h>
#include <Windows.h>
#include <commctrl.h>
#include <shlwapi.h>
#include "res\resource.h"
#include <vector>
#include <string>
#include "hsUtils.h"
#include "pfLocalizationMgr/pfLocalizationDataMgr.h"
extern HINSTANCE gInstance;
std::wstring plLocTreeView::fPath = L"";
HTREEITEM AddLeaf(HWND hTree, HTREEITEM hParent, std::wstring text, bool sort = true)
{
TVITEM tvi = {0};
tvi.mask = TVIF_TEXT | TVIF_PARAM;
tvi.pszText = (wchar_t*)text.c_str();
tvi.cchTextMax = (int)text.length();
tvi.lParam = NULL;
TVINSERTSTRUCT tvins = {0};
tvins.item = tvi;
tvins.hParent = hParent;
if (sort)
tvins.hInsertAfter = TVI_SORT;
else
tvins.hInsertAfter = TVI_LAST;
return TreeView_InsertItem(hTree, &tvins);
}
void plLocTreeView::FillTreeViewFromData(HWND treeCtrl, std::wstring selectionPath)
{
std::wstring 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();
for (int curAge = 0; curAge < ages.size(); curAge++)
{
// add the age to the tree
HTREEITEM ageItem = AddLeaf(treeCtrl, NULL, ages[curAge]);
if (ages[curAge] == targetAge)
{
TreeView_SelectItem(treeCtrl, ageItem);
TreeView_EnsureVisible(treeCtrl, ageItem);
ageMatched = true;
}
else
ageMatched = false;
std::vector<std::wstring> 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]);
HTREEITEM setItem = AddLeaf(treeCtrl, ageItem, sets[curSet]);
if ((sets[curSet] == targetSet) && ageMatched)
{
TreeView_SelectItem(treeCtrl, setItem);
TreeView_EnsureVisible(treeCtrl, setItem);
setMatched = true;
}
else
setMatched = false;
for (int curElement = 0; curElement < elements.size(); curElement++)
{
HTREEITEM subItem = AddLeaf(treeCtrl, setItem, elements[curElement]);
if (elements[curElement] == targetElement && setMatched)
{
TreeView_SelectItem(treeCtrl, subItem);
TreeView_EnsureVisible(treeCtrl, subItem);
elementMatched = true;
if (targetLang.empty())
targetLang = L"English";
}
else
elementMatched = false;
std::vector<std::wstring> 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]);
if (languages[curLang] == targetLang && elementMatched)
{
TreeView_SelectItem(treeCtrl, langItem);
TreeView_EnsureVisible(treeCtrl, langItem);
}
}
}
}
}
}
void plLocTreeView::ClearTreeView(HWND treeCtrl)
{
TreeView_DeleteAllItems(treeCtrl);
}
void plLocTreeView::SelectionChanged(HWND treeCtrl)
{
HTREEITEM hItem = TreeView_GetSelection(treeCtrl);
std::vector<std::wstring> path;
fPath = L"";
while (hItem)
{
wchar_t s[200];
TVITEM tvi = {0};
tvi.hItem = hItem;
tvi.mask = TVIF_TEXT;
tvi.pszText = s;
tvi.cchTextMax = 200;
TreeView_GetItem(treeCtrl, &tvi);
path.push_back(tvi.pszText);
hItem = TreeView_GetParent(treeCtrl, hItem);
}
while (!path.empty())
{
fPath += path.back();
path.pop_back();
if (!path.empty())
fPath += L".";
}
}
void plLocTreeView::SelectionDblClicked(HWND treeCtrl)
{
HTREEITEM hItem = TreeView_GetSelection(treeCtrl);
std::vector<std::wstring> path;
fPath = L"";
while (hItem)
{
wchar_t s[200];
TVITEM tvi = {0};
tvi.hItem = hItem;
tvi.mask = TVIF_TEXT;
tvi.pszText = s;
tvi.cchTextMax = 200;
TreeView_GetItem(treeCtrl, &tvi);
path.push_back(tvi.pszText);
hItem = TreeView_GetParent(treeCtrl, hItem);
}
while (!path.empty())
{
fPath += path.back();
path.pop_back();
if (!path.empty())
fPath += L".";
}
}

65
Sources/Tools/plLocalizationEditor/plLocTreeView.h

@ -0,0 +1,65 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#ifndef _plLocTreeView_h
#define _plLocTreeView_h
#define WIN32_LEAN_AND_MEAN
#include <WinSock2.h>
#include <Windows.h>
#include <string>
class plLocTreeView
{
protected:
static std::wstring fPath;
public:
static void FillTreeViewFromData(HWND treeCtrl, std::wstring selectionPath);
static void ClearTreeView(HWND treeCtrl);
static void SelectionChanged(HWND treeCtrl);
static void SelectionDblClicked(HWND treeCtrl);
static std::wstring GetPath() {return fPath;}
};
#endif //_plLocTreeView_h

394
Sources/Tools/plLocalizationEditor/plLocalizationEditor.cpp

@ -0,0 +1,394 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#define CLASSNAME L"plLocalizationEditor"
#define WINDOWNAME L"plLocalizationEditor"
#define IDC_REGTREEVIEW 1000
#define FILE_MENU_POS 0 // 0-based index of the file sub menu
#include "pnAllCreatables.h"
#include "plResMgr/plResMgrCreatable.h"
// These are so that we don't have to link in stuff we don't have to
#include "plMessage/plResMgrHelperMsg.h"
#include "plMessage/plAgeLoadedMsg.h"
REGISTER_CREATABLE(plResMgrHelperMsg);
REGISTER_CREATABLE(plAgeLoadedMsg);
REGISTER_CREATABLE(plAgeLoaded2Msg);
REGISTER_CREATABLE(plAgeBeginLoadingMsg);
REGISTER_CREATABLE(plInitialAgeStateLoadedMsg);
#include "pfLocalizationMgr/pfLocalizationMgr.h"
#include "pfLocalizationMgr/pfLocalizationDataMgr.h"
#include "plResMgr/plResManager.h"
#include "plLocTreeView.h"
#include "plEditDlg.h"
#define WIN32_LEAN_AND_MEAN
#include <WinSock2.h>
#include <Windows.h>
#include <Commdlg.h>
#include <stdio.h>
#include <commctrl.h>
#include <shlwapi.h>
#include <shlobj.h>
#include "res/resource.h"
HINSTANCE gInstance = NULL;
HWND gMainWindow = NULL;
HWND gTreeView = NULL; // the tree view for display of localization strings
extern HWND gEditDlg; // the main edit dialog for the localization strings
std::wstring gCurPath = L""; // current data path
LRESULT CALLBACK MainWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
BOOL WinInit(HINSTANCE hInst, int nCmdShow);
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
HACCEL accelTable = LoadAccelerators(hInst, MAKEINTRESOURCE(IDR_ACCELERATOR1));
if (!WinInit(hInst, nCmdShow))
return -1;
plResManager *rMgr = new plResManager;
hsgResMgr::Init(rMgr);
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(gMainWindow, accelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
pfLocalizationMgr::Shutdown();
hsgResMgr::Shutdown();
return 0;
}
BOOL WinInit(HINSTANCE hInst, int nCmdShow)
{
LoadLibrary(L"Riched20.dll"); // so we can use our rich edit control
gInstance = hInst;
WNDCLASSEX wcEx;
wcEx.cbSize = sizeof(WNDCLASSEX);
wcEx.style = CS_HREDRAW | CS_VREDRAW;
wcEx.lpfnWndProc = MainWndProc;
wcEx.cbClsExtra = 0;
wcEx.cbWndExtra = 0;
wcEx.hInstance = hInst;
wcEx.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_APPICON));
wcEx.hCursor = LoadCursor(NULL, IDC_ARROW);
wcEx.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
wcEx.lpszMenuName = MAKEINTRESOURCE(IDR_APPMENU);
wcEx.lpszClassName = CLASSNAME;
wcEx.hIconSm = (HICON)LoadImage(hInst, MAKEINTRESOURCE(IDI_APPICON), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_DEFAULTCOLOR);
if (!RegisterClassEx(&wcEx))
return FALSE;
DWORD dwStyle = WS_POPUP | WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VISIBLE;
DWORD dwExStyle = WS_EX_CONTROLPARENT;
// Create a window
gMainWindow = CreateWindowEx(dwExStyle, CLASSNAME, WINDOWNAME, dwStyle, 10, 10, 800, 500, NULL, NULL, hInst, NULL);
if (gMainWindow == NULL)
return FALSE;
return TRUE;
}
void SetWindowTitle(HWND hWnd, std::wstring path)
{
std::wstring title = L"plLocalizationEditor";
if (path != L"")
title += L"-" + path;
SetWindowText(hWnd, title.c_str());
}
BOOL CALLBACK AboutDialogProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
if(msg == WM_COMMAND)
EndDialog(hWnd, 0);
return 0;
}
void RequestSaveOnExit()
{
if (gCurPath == L"") // no data open
return;
static bool alreadyRequested = false; // make sure we don't ask multiple times
if (alreadyRequested)
return;
alreadyRequested = true;
SaveLocalizationText(); // make sure any changed text is saved to the manager
int res = MessageBox(NULL, L"Do you wish to save your changes?", L"Save Changes", MB_ICONQUESTION | MB_YESNO);
if (res == IDYES)
{
// save it to a new directory
BROWSEINFO bInfo;
LPITEMIDLIST itemList;
LPMALLOC shMalloc;
wchar_t path[MAX_PATH];
memset(&bInfo, 0, sizeof(bInfo));
bInfo.hwndOwner = NULL;
bInfo.pidlRoot = NULL;
bInfo.pszDisplayName = path;
bInfo.lpszTitle = L"Select a directory to save the localization data to:";
bInfo.ulFlags = BIF_EDITBOX;
itemList = SHBrowseForFolder(&bInfo);
if (itemList != NULL)
{
plWaitCursor waitCursor;
SHGetPathFromIDList(itemList, path);
SHGetMalloc(&shMalloc);
shMalloc->Free(itemList);
shMalloc->Release();
gCurPath = path;
char *sPath = hsWStringToString(gCurPath.c_str());
pfLocalizationDataMgr::Instance().WriteDatabaseToDisk(sPath);
delete [] sPath;
}
}
}
LRESULT CALLBACK HandleCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
switch (LOWORD(wParam))
{
case ID_FILE_EXIT:
RequestSaveOnExit();
PostQuitMessage(0);
break;
case ID_FILE_OPENDATADIRECTORY:
{
BROWSEINFO bInfo;
LPITEMIDLIST itemList;
LPMALLOC shMalloc;
wchar_t path[MAX_PATH];
memset(&bInfo, 0, sizeof(bInfo));
bInfo.hwndOwner = hWnd;
bInfo.pidlRoot = NULL;
bInfo.pszDisplayName = path;
bInfo.lpszTitle = L"Select a localization data directory:";
bInfo.ulFlags = BIF_EDITBOX;
itemList = SHBrowseForFolder(&bInfo);
if (itemList != NULL)
{
plWaitCursor waitCursor;
SHGetPathFromIDList(itemList, path);
SHGetMalloc(&shMalloc);
shMalloc->Free(itemList);
shMalloc->Release();
pfLocalizationMgr::Shutdown();
char *sPath = hsWStringToString(path);
pfLocalizationMgr::Initialize(sPath);
delete [] sPath;
plLocTreeView::ClearTreeView(gTreeView);
plLocTreeView::FillTreeViewFromData(gTreeView, L"");
gCurPath = path;
SetWindowTitle(hWnd, path);
HMENU menu = GetMenu(hWnd);
HMENU fileMenu = GetSubMenu(menu, FILE_MENU_POS);
EnableMenuItem(fileMenu, ID_FILE_SAVETOCUR, MF_ENABLED);
EnableMenuItem(fileMenu, ID_FILE_SAVETONEW, MF_ENABLED);
}
}
break;
case ID_FILE_SAVETOCUR:
{
SaveLocalizationText(); // make sure any changed text is saved to the manager
// save it to our current directory
int res = MessageBox(hWnd, L"Are you sure you want to save to the current directory? Current data will be overwritten!", L"Save to Current Directory", MB_ICONQUESTION | MB_YESNOCANCEL);
if (res == IDYES)
{
plWaitCursor waitCursor;
char *sPath = hsWStringToString(gCurPath.c_str());
pfLocalizationDataMgr::Instance().WriteDatabaseToDisk(sPath);
delete [] sPath;
}
else if (res == IDNO)
SendMessage(hWnd, WM_COMMAND, (WPARAM)ID_FILE_SAVETONEW, (LPARAM)0);
// and if it's cancel we don't do anything
}
break;
case ID_FILE_SAVETONEW:
{
SaveLocalizationText(); // make sure any changed text is saved to the manager
// save it to a new directory
BROWSEINFO bInfo;
LPITEMIDLIST itemList;
LPMALLOC shMalloc;
wchar_t path[MAX_PATH];
memset(&bInfo, 0, sizeof(bInfo));
bInfo.hwndOwner = hWnd;
bInfo.pidlRoot = NULL;
bInfo.pszDisplayName = path;
bInfo.lpszTitle = L"Select a directory to save the localization data to:";
bInfo.ulFlags = BIF_EDITBOX;
itemList = SHBrowseForFolder(&bInfo);
if (itemList != NULL)
{
plWaitCursor waitCursor;
SHGetPathFromIDList(itemList, path);
SHGetMalloc(&shMalloc);
shMalloc->Free(itemList);
shMalloc->Release();
gCurPath = path;
SetWindowTitle(hWnd, path);
char *sPath = hsWStringToString(gCurPath.c_str());
pfLocalizationDataMgr::Instance().WriteDatabaseToDisk(sPath);
delete [] sPath;
}
}
break;
case ID_HELP_ABOUT:
DialogBox(gInstance, MAKEINTRESOURCE(IDD_ABOUT), hWnd, AboutDialogProc);
break;
}
return 0;
}
void SizeControls(HWND parent)
{
RECT clientRect, editRect;
GetClientRect(parent, &clientRect);
GetClientRect(gEditDlg, &editRect);
SetWindowPos(gTreeView, NULL, 0, 0, clientRect.right - editRect.right - 4, clientRect.bottom, 0);
OffsetRect(&editRect, clientRect.right - editRect.right, (clientRect.bottom >> 1) - (editRect.bottom >> 1));
SetWindowPos(gEditDlg, NULL, editRect.left, editRect.top, 0, 0, SWP_NOSIZE);
}
void InitWindowControls(HWND hWnd)
{
RECT clientRect;
GetClientRect(hWnd, &clientRect);
gTreeView = CreateWindowEx(WS_EX_CLIENTEDGE, WC_TREEVIEW, L"Tree View", WS_VISIBLE | WS_CHILD | WS_BORDER |
TVS_HASLINES | TVS_HASBUTTONS | TVS_LINESATROOT | TVS_SHOWSELALWAYS,
0, 0, 0, 0, hWnd, (HMENU)IDC_REGTREEVIEW, gInstance, NULL);
gEditDlg = CreateDialog(gInstance, MAKEINTRESOURCE(IDD_EDITDLG), hWnd, EditDlgProc);
SizeControls(hWnd);
}
LRESULT CALLBACK MainWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_CREATE:
InitCommonControls();
InitWindowControls(hWnd);
break;
case WM_CLOSE:
RequestSaveOnExit();
DestroyWindow(hWnd);
break;
case WM_DESTROY:
RequestSaveOnExit();
plLocTreeView::ClearTreeView(gTreeView);
PostQuitMessage(0);
break;
case WM_SIZING:
case WM_SIZE:
SizeControls(hWnd);
break;
case WM_GETMINMAXINFO:
{
MINMAXINFO* pmmi = (MINMAXINFO*)lParam;
pmmi->ptMinTrackSize.x = 800;
pmmi->ptMinTrackSize.y = 500;
return 0;
}
case WM_NOTIFY:
if(wParam == IDC_REGTREEVIEW)
{
SaveLocalizationText(); // save any current changes to the database
NMHDR *hdr = (NMHDR*)lParam;
if(hdr->code == TVN_SELCHANGED)
plLocTreeView::SelectionChanged(gTreeView);
else if(hdr->code == NM_DBLCLK)
plLocTreeView::SelectionDblClicked(gTreeView);
UpdateEditDlg(plLocTreeView::GetPath());
}
break;
case WM_COMMAND:
return HandleCommand(hWnd, wParam, lParam);
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}

BIN
Sources/Tools/plLocalizationEditor/res/icon1.ico

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

268
Sources/Tools/plLocalizationEditor/res/plLocalizationEditor.rc

@ -0,0 +1,268 @@
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#define APSTUDIO_HIDDEN_SYMBOLS
#include "windows.h"
#undef APSTUDIO_HIDDEN_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDI_APPICON ICON "icon1.ico"
/////////////////////////////////////////////////////////////////////////////
//
// Menu
//
IDR_APPMENU MENU
BEGIN
POPUP "&File"
BEGIN
MENUITEM "&Open Data Directory...\tCtrl+O",
ID_FILE_OPENDATADIRECTORY
MENUITEM SEPARATOR
MENUITEM "&Save to Current Directory\tCtrl+S", ID_FILE_SAVETOCUR
, GRAYED
MENUITEM "S&ave to Specified Directory...\tCtrl+Shift+S",
ID_FILE_SAVETONEW, GRAYED
MENUITEM SEPARATOR
MENUITEM "E&xit", ID_FILE_EXIT
END
POPUP "&Help"
BEGIN
MENUITEM "&About ...", ID_HELP_ABOUT
END
END
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_ABOUT DIALOGEX 0, 0, 275, 40
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION |
WS_SYSMENU
CAPTION "About plLocalizationEditor"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "OK",IDOK,221,6,50,14
ICON IDI_APPICON,IDC_STATIC,7,7,21,20
LTEXT "plLocalizationEditor\nA basic editor for Plasma 21 localization resource files\nCopyright (C) 2004 Cyan Worlds, Inc.",
IDC_STATIC,33,7,180,26
END
IDD_EDITDLG DIALOGEX 0, 0, 421, 280
STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_VISIBLE
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
PUSHBUTTON "Add",IDC_ADD,72,20,138,14,WS_DISABLED
PUSHBUTTON "Delete",IDC_DELETE,216,20,132,14,WS_DISABLED
GROUPBOX "Localization Tree",IDC_STATIC,7,7,407,32
GROUPBOX "Localization Information",IDC_STATIC,7,45,407,228
LTEXT "Text:",IDC_LOCPATH,15,57,391,8
CONTROL "",IDC_LOCALIZATIONTEXT,"RichEdit20A",ES_MULTILINE |
ES_AUTOHSCROLL | WS_DISABLED | WS_BORDER | WS_VSCROLL |
WS_HSCROLL | WS_TABSTOP,15,71,391,194
END
IDD_ADDELEMENT DIALOGEX 0, 0, 186, 91
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION |
WS_SYSMENU
CAPTION "Add Element"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
COMBOBOX IDC_PARENTAGE,57,19,122,51,CBS_DROPDOWN | CBS_SORT |
WS_VSCROLL | WS_TABSTOP
COMBOBOX IDC_PARENTSET,57,34,122,51,CBS_DROPDOWN | CBS_SORT |
WS_VSCROLL | WS_TABSTOP
EDITTEXT IDC_ELEMENTNAME,57,49,122,14,ES_AUTOHSCROLL
DEFPUSHBUTTON "OK",IDOK,129,70,50,14
PUSHBUTTON "Cancel",IDCANCEL,73,70,50,14
LTEXT "Path:",IDC_PATH,7,7,172,8
LTEXT "Parent Age:",IDC_STATIC,7,22,48,8
LTEXT "Parent Set:",IDC_STATIC,7,37,38,8
LTEXT "Element Name:",IDC_STATIC,7,52,49,8
END
IDD_ADDLOCALIZATION DIALOGEX 0, 0, 186, 59
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION |
WS_SYSMENU
CAPTION "Add Localization"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
COMBOBOX IDC_LANGUAGE,45,19,134,65,CBS_DROPDOWNLIST | CBS_SORT |
WS_VSCROLL | WS_TABSTOP
DEFPUSHBUTTON "OK",IDOK,129,38,50,14
PUSHBUTTON "Cancel",IDCANCEL,73,38,50,14
LTEXT "Path:",IDC_PATH,7,7,172,8
LTEXT "Language:",IDC_STATIC,7,21,35,8
END
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,0,0,1
PRODUCTVERSION 1,0,0,1
FILEFLAGSMASK 0x17L
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x40004L
FILETYPE 0x1L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "CompanyName", "Cyan Worlds, Inc."
VALUE "FileDescription", "plLocalizationEditor"
VALUE "FileVersion", "1, 0, 0, 1"
VALUE "InternalName", "plLocalizationEditor"
VALUE "LegalCopyright", "Copyright © 2004"
VALUE "OriginalFilename", "plLocalizationEditor.exe"
VALUE "ProductName", "Cyan Worlds Localization Editor"
VALUE "ProductVersion", "1, 0, 0, 1"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"#define APSTUDIO_HIDDEN_SYMBOLS\r\n"
"#include ""windows.h""\r\n"
"#undef APSTUDIO_HIDDEN_SYMBOLS\r\n"
"\0"
END
3 TEXTINCLUDE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGIN
IDD_ABOUT, DIALOG
BEGIN
RIGHTMARGIN, 252
END
IDD_EDITDLG, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 414
VERTGUIDE, 15
VERTGUIDE, 72
VERTGUIDE, 210
VERTGUIDE, 216
VERTGUIDE, 348
VERTGUIDE, 406
TOPMARGIN, 7
BOTTOMMARGIN, 273
HORZGUIDE, 71
HORZGUIDE, 265
END
IDD_ADDELEMENT, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 179
TOPMARGIN, 7
BOTTOMMARGIN, 84
END
IDD_ADDLOCALIZATION, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 179
TOPMARGIN, 7
BOTTOMMARGIN, 52
END
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Accelerator
//
IDR_ACCELERATOR1 ACCELERATORS
BEGIN
"O", ID_FILE_OPENDATADIRECTORY, VIRTKEY, CONTROL, NOINVERT
"S", ID_FILE_SAVETOCUR, VIRTKEY, CONTROL, NOINVERT
"S", ID_FILE_SAVETONEW, VIRTKEY, SHIFT, CONTROL,
NOINVERT
END
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

51
Sources/Tools/plLocalizationEditor/res/resource.h

@ -0,0 +1,51 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by plLocalizationEditor.rc
//
#define IDC_MYICON 2
#define IDI_APPICON 102
#define IDD_PLLOCALIZATIONEDITOR_DIALOG 102
#define IDS_APP_TITLE 103
#define IDD_ABOUTBOX 103
#define IDI_PLLOCALIZATIONEDITOR 107
#define IDI_SMALL 108
#define IDC_PLLOCALIZATIONEDITOR 109
#define IDR_APPMENU 109
#define IDD_ADDELEMENT 113
#define IDD_ADDLOCALIZATION 114
#define IDR_MAINFRAME 128
#define IDD_ABOUT 129
#define IDR_ACCELERATOR1 130
#define IDD_EDITDLG 131
#define IDC_RICHEDIT21 1000
#define IDC_LOCALIZATIONTEXT 1002
#define IDC_APPLY 1014
#define IDC_DISCARD 1015
#define IDC_LOCPATH 1019
#define IDC_ADD 1020
#define IDC_DELETE 1021
#define IDC_PATH 1023
#define IDC_PARENTSET 1026
#define IDC_ELEMENTNAME 1027
#define IDC_PARENTAGE 1028
#define IDC_LANGUAGE 1028
#define ID_FILE_EXIT 32772
#define ID_HELP_ABOUT 32773
#define ID_FILE_OPENDATADIRECTORY 32774
#define ID_FILE_SAVETOSPECIFIEDDIRECTORY 32778
#define ID_FILE_SAVETOCURRENTDIRECTORY 32779
#define ID_FILE_SAVETOCUR 32782
#define ID_FILE_SAVETONEW 32783
#define IDC_STATIC -1
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NO_MFC 1
#define _APS_NEXT_RESOURCE_VALUE 132
#define _APS_NEXT_COMMAND_VALUE 32784
#define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 110
#endif
#endif
Loading…
Cancel
Save