khanat-opennel-code/code/ryzom/tools/leveldesign/variable_parser/variable_parserDlg.cpp
2010-05-08 15:37:08 +02:00

500 lines
12 KiB
C++

// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero 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 Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
// VariableParserDlg.cpp : implementation file
//
#include "stdafx.h"
#include "variable_parser.h"
#include "variable_parserDlg.h"
/*#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif*/
using namespace NLMISC;
using namespace std;
/////////////////////////////////////////////////////////////////////////////
// CVariableParserDlg dialog
CVariableParserDlg::CVariableParserDlg(CWnd* pParent /*=NULL*/)
: CDialog(CVariableParserDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CVariableParserDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
CVariableParserDlg::~CVariableParserDlg()
{
m_nomVariables.clear();
for ( uint i=0; i<m_variables.size(); i++ )
{
m_variables[i].clear();
}
m_variables.clear();
}
void CVariableParserDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CVariableParserDlg)
DDX_Control(pDX, IDC_VARDEF, m_varDefList);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CVariableParserDlg, CDialog)
//{{AFX_MSG_MAP(CVariableParserDlg)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_HDR_BROWSE, OnHdrBrowse)
ON_BN_CLICKED(IDC_TMPL_BROWSE, OnTmplBrowse)
ON_BN_CLICKED(IDC_FOOT_BROWSE, OnFootBrowse)
ON_BN_CLICKED(IDC_OUTPUT_BROWSE, OnOutputBrowse)
ON_BN_CLICKED(IDC_GENERATE, OnGenerate)
ON_BN_CLICKED(IDC_GEN_BROWSE, OnGenBrowse)
ON_BN_CLICKED(IDC_LUA_BROWSE, OnLUABrowse)
ON_BN_CLICKED(IDC_ADDVARDEF, OnAddvardef)
ON_BN_CLICKED(IDC_REMVARDEF, OnRemvardef)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CVariableParserDlg message handlers
BOOL CVariableParserDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
return TRUE; // return TRUE unless you set the focus to a control
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CVariableParserDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CVariableParserDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CVariableParserDlg::OnHdrBrowse()
{
CFileDialog fileDlg( TRUE, NULL, NULL, OFN_OVERWRITEPROMPT, "Primitive file (*.primitive)|*.primitive||");
if ( fileDlg.DoModal() == IDOK )
{
GetDlgItem( IDC_HDR_FILE )->SetWindowText( fileDlg.GetPathName() );
}
}
void CVariableParserDlg::OnTmplBrowse()
{
CFileDialog fileDlg( TRUE, NULL, NULL, OFN_OVERWRITEPROMPT, "Primitive file (*.primitive)|*.primitive||");
if ( fileDlg.DoModal() == IDOK )
{
GetDlgItem( IDC_TMPL_FILE )->SetWindowText( fileDlg.GetPathName() );
}
}
void CVariableParserDlg::OnFootBrowse()
{
CFileDialog fileDlg( TRUE, NULL, NULL, OFN_OVERWRITEPROMPT, "Primitive file (*.primitive)|*.primitive||");
if ( fileDlg.DoModal() == IDOK )
{
GetDlgItem( IDC_FOOT_FILE )->SetWindowText( fileDlg.GetPathName() );
}
}
void CVariableParserDlg::OnOutputBrowse()
{
CFileDialog fileDlg( FALSE, NULL, NULL, OFN_OVERWRITEPROMPT, "Primitive file (*.primitive)|*.primitive||");
if ( fileDlg.DoModal() == IDOK )
{
GetDlgItem( IDC_OUTPUT_FILE )->SetWindowText( fileDlg.GetPathName() );
}
}
void CVariableParserDlg::OnGenBrowse()
{
CFileDialog fileDlg( TRUE, NULL, NULL, OFN_OVERWRITEPROMPT, "Comma Separated Values (*.csv)|*.csv||");
if ( fileDlg.DoModal() == IDOK )
{
GetDlgItem( IDC_GEN_FILE )->SetWindowText( fileDlg.GetPathName() );
}
}
void CVariableParserDlg::OnLUABrowse()
{
CFileDialog fileDlg( TRUE, NULL, NULL, OFN_OVERWRITEPROMPT, "Lua files (*.lua)|*.lua||");
if ( fileDlg.DoModal() == IDOK )
{
GetDlgItem( IDC_LUA_FILE )->SetWindowText( fileDlg.GetPathName() );
}
}
void CleanString( CSString &str )
{
int i = str.size();
bool ok = false;
while ( !ok && ( i > 0 ) )
{
char c = str.c_str()[i-1];
if ( !isalpha(c) && !isdigit(c) && ( c != '_' ) && ( c != ')' ) )
{
i--;
}
else
ok = true;
}
str = str.left( i );
}
void CVariableParserDlg::ProcessGeneratorFile( const string& generatorFile )
{
CSString genData, ligne;
int colonneVar = 0;
genData.readFromFile( generatorFile );
ligne = genData.splitTo( "\n", true );
while ( ligne != "" )
{
CSString var = ligne.splitTo( ";", true );
CleanString( var );
if ( var != "" )
{
m_nomVariables.push_back( var ) ;
vector<string> vec;
m_variables.push_back( vec );
}
}
while ( genData != "" )
{
ligne = genData.splitTo( "\n", true );
if ( ligne != "" )
{
for ( uint i=0;i<m_variables.size(); i++)
{
CSString var = ligne.splitTo( ";", true );
CleanString( var );
if ( var != "" )
{
m_variables[i].push_back( var );
}
}
}
}
ParseParameters params;
BuildParseParameters( params, 0, 0 );
}
void CVariableParserDlg::BuildParseParameters( ParseParameters& params, uint ligne, uint colonne )
{
CSString left = CSString( m_nomVariables[ colonne ] ).left(2);
if ( left == "@@" )
{
//if ( colonne+1 >= params.capacity() )
params.push_back( "" );
CString str = m_variables[colonne][ligne].c_str();
params[colonne] = str;
if ( colonne+1 == m_variables.size() )
{
ParseTemplate( params );
}
else
{
BuildParseParameters( params, ligne, colonne+1 );
}
}
else if ( left == "##" )
{
params.push_back( "" );
CString str = m_variables[colonne][0].c_str();
for ( uint j=m_nomVariables.size(); j>0; j-- )
{
str.Replace( toString( "C%d", j-1 ).c_str(), params[j-1].c_str() );
}
try
{
m_luaState.executeScript( str.GetBuffer( str.GetLength() ) );
}
catch (ELuaError &e)
{
MessageBox( toString( "%s", e.luaWhat().c_str() ).c_str() );
return;
}
m_luaState.push("VAL");
m_luaState.getTable(LUA_GLOBALSINDEX);
bool ok= false;
sint type= m_luaState.type();
if ( type == LUA_TBOOLEAN )
{
// get and pop
bool val= m_luaState.toBoolean();
m_luaState.pop();
// set result
if ( val )
str = "TRUE";
else
str = "FALSE";
ok = true;
}
else if ( type == LUA_TNUMBER )
{
// get and pop
double val= m_luaState.toNumber();
m_luaState.pop();
// set double or integer?
if ( val == floor( val ) )
str.Format( "%d", sint64( floor( val ) ) );
else
str.Format( "%.3f", val );
ok = true;
}
else if ( type == LUA_TSTRING )
{
// get and pop
std::string val;
m_luaState.toString(-1, val);
m_luaState.pop();
// set result
str = val.c_str();
ok = true;
}
if ( !ok )
{
MessageBox( toString( "VAL is not defined on column %d", colonne ).c_str() );
}
else
{
params[colonne] = str;
if ( colonne+1 == m_variables.size() )
{
ParseTemplate( params );
}
else
{
BuildParseParameters( params, ligne, colonne+1 );
}
}
}
else
{
for ( uint i=0; i<m_variables[colonne].size(); i++ )
{
//if ( colonne+1 >= params.capacity() )
params.push_back( "" );
CString str;
str = m_variables[colonne][i].c_str();
params[colonne] = str;
if ( colonne+1 == m_variables.size() )
{
ParseTemplate( params );
}
else
{
BuildParseParameters( params, i, colonne+1 );
}
}
}
}
void CVariableParserDlg::ParseTemplate( const ParseParameters& params )
{
CString tmp = m_templateText.c_str();
for ( uint i=0; i< m_nomVariables.size(); i++ )
{
CSString toFind;
if ( CSString( m_nomVariables[ i ] ).left(2) == "@@" )
{
toFind = toString( "%s", m_nomVariables[i].c_str() );
}
else if ( CSString( m_nomVariables[ i ] ).left(2) == "##" )
{
toFind = toString( "%s", m_nomVariables[i].c_str() );
}
else
toFind = toString( "$$%s", m_nomVariables[i].c_str() );
tmp.Replace( toFind.c_str(), params[i].c_str() );
}
m_outputText += tmp;
}
void CVariableParserDlg::OnGenerate()
{
CString error = "";
CSString hdr, foot;
CString hdrFilename, templFileName, footFileName,
outputFileName, luaFileName;
GetDlgItem( IDC_HDR_FILE )->GetWindowText( hdrFilename );
if ( hdrFilename == "" )
error += "Header file name not set.\n";
GetDlgItem( IDC_FOOT_FILE )->GetWindowText( footFileName );
if ( footFileName == "" )
error += "Foot file name not set.\n";
GetDlgItem( IDC_TMPL_FILE )->GetWindowText( templFileName );
if ( templFileName == "" )
error += "Template file name not set.\n";
if ( m_varDefList.GetCount() == 0 )
error += "Generator file name not set.\n";
GetDlgItem( IDC_OUTPUT_FILE )->GetWindowText( outputFileName );
if ( outputFileName == "" )
error += "Output file name not set.";
if ( error != "" )
{
MessageBox( error, NULL, MB_OK );
}
else
{
GetDlgItem( IDC_LUA_FILE )->GetWindowText( luaFileName );
if ( luaFileName != "" )
{
m_luaState.executeFile( std::string( luaFileName ) );
}
hdr.readFromFile( std::string( hdrFilename ) );
foot.readFromFile( std::string( footFileName ) );
m_templateText.readFromFile( std::string( templFileName ) );
m_outputText = hdr;
for ( int i=0; i<m_varDefList.GetCount(); i++ )
{
CString str;
m_varDefList.GetText( i, str );
ProcessGeneratorFile( std::string( str ) );
m_variables.clear();
}
m_outputText += foot;
m_outputText.writeToFile( std::string( outputFileName ) );
MessageBox( "Done !" );
}
}
void CVariableParserDlg::OnAddvardef()
{
CFileDialog fileDlg( TRUE, NULL, NULL, OFN_OVERWRITEPROMPT|OFN_ALLOWMULTISELECT,
"Comma Separated Values (*.csv)|*.csv||");
if ( fileDlg.DoModal() == IDOK )
{
for ( POSITION pos = fileDlg.GetStartPosition(); pos != NULL; )
{
CString str = fileDlg.GetNextPathName(pos);
int index = m_varDefList.FindStringExact( 0, str );
if ( index == LB_ERR )
{
m_varDefList.SetCurSel( m_varDefList.AddString( str ) );
}
else
m_varDefList.SetCurSel( index );
}
}
}
void CVariableParserDlg::OnRemvardef()
{
int index = m_varDefList.GetCurSel();
if ( index != LB_ERR )
m_varDefList.DeleteString( index );
}