/*==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 3 ds 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 , 3 ds 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 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 ) ;
}